Reputation: 5113
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
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
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
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
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
Reputation: 16851
The simplest solution is to use the shift
and push
operators.
shift
will remove an element from the start of an arraypush
will add an element to the end of an arrayIf 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);
}
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);
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.
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));
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
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