uber
uber

Reputation: 5113

Change array order at any given index

Given the following array

const arr = [13, 6075, 51]

I would like to modify the above array in this way:

// result if the selected index was `1`:
[6075, 51, 13]

// result if the selected index was `2`:
[51, 13, 6075]

I have been able to do this with 'slice' but on a copy of the array, not on the array I'd like to modify itself.

Upvotes: 1

Views: 74

Answers (6)

Ran Turner
Ran Turner

Reputation: 18156

This will do the job:

const shiftArray = (array, idx) => array.concat(array.splice(0, idx));

shiftArray([13, 6075, 51], 1) //[6075, 51, 13]
shiftArray([13, 6075, 51], 2) //[51, 13, 6075]

Upvotes: 1

Majed Badawi
Majed Badawi

Reputation: 28434

You can use .slice two get the two parts, and .concat to return the result:

const swapPartsAtIndex = (arr=[], index=-1) => {
  if(index <= 0 || index >= arr.length) return arr;
  return arr.slice(index,arr.length).concat(arr.slice(0,index));
}

let arr = [0,1,2,3,4,5];
arr = swapPartsAtIndex(arr, 3);
console.log(...arr);

arr = swapPartsAtIndex([0,1,2,3,4,5,6], 3);
console.log(...arr);

Upvotes: 1

Pablo Darde
Pablo Darde

Reputation: 6432

const myArray = [13, 6075, 51, 44, 67, 78]


function shiftArrayEntries(arr, index) {
   const shiftedEntries = arr.splice(0, index)
   
   return arr.concat(shiftedEntries)
}

console.log(shiftArrayEntries(myArray, 3))

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386881

You could change the length of the array and take Array#copyWithin for moving values.

At the end change the length back.

function move(array, index) {
    const l = array.length;
    array.length += index;
    array.copyWithin(l, 0, index);
    array.copyWithin(0, index, index + l);
    array.length = l;
}

const array = [13, 6075, 51];


move(array, 1);
console.log(...array);

Upvotes: 1

stevendesu
stevendesu

Reputation: 16851

Simple Answer

The simplest solution is to use the shift and push operators.

  • shift will remove an element from the start of an array
  • push will add an element to the end of an array

If you perform these two operations in sequence then it will take one element from the start and put it on the end, like so:

var arr = [1, 2, 3, 4];
var element = arr.shift();
arr.push(element);
console.log(arr); // [2, 3, 4, 1]

Using a for loop you can do this "N" times:

for (var i = 0; i < n; i++) {
    var element = arr.shift();
    arr.push(element);
}

More Efficient Answer

If you're not constrained by memory, you can just operate on a copy of the array (as you said you've done) and then overwrite the original:

var removedElements = arr.splice(0, n);
arr = arr.concat(removedElements);

More Efficient In-Place Answer

You can push multiple elements at once using Array.prototype.push.apply() like so:

var removedElements = arr.splice(0, n);
Array.prototype.push.apply(arr, removedElements);

This is one of the "better" answers, but requires understanding of prototypes - so I saved it for last.

ES6 Answer

Using modern JavaScript notation you can actually perform Array.prototype.push.apply without any ugliness:

var removedElements = arr.splice(0, n);
ar.push(...removedElements);

The above can be turned into a one-liner:

arr.push(...arr.splice(0, n));

Functional Programming Answer

The operation you're performing is called a "rotation" on the array. Sometimes also referred to as "cycling". You may be able to find a functional programming library that will give you a rotate method, allowing code like:

arr.rotate(n);

I took a quick look and a function like this was requested in Lodash, but it was rejected and never implemented: https://github.com/lodash/lodash/issues/2173

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1075925

One approach is to do the removal via splice, which will give you an array of what was removed, then use push to add those things back at the end:

function swap(arr, index) {
    const removed = arr.splice(0, index);
    arr.push(...removed);
    return arr; // Just for chaining, the array is modified in place
}

Live Example:

const arr = [13, 6075, 51];

function swap(arr, index) {
    const removed = arr.splice(0, index);
    arr.push(...removed);
    return arr;
}

console.log(swap([13, 6075, 51], 1));
console.log(swap([13, 6075, 51], 2));

Upvotes: 2

Related Questions