If you'd like a version on npm, array-move is the closest to this answer, although it's not the same implementation. See its usage section for more details. The previous version of this answer (that modified Array.prototype.move) can be found on npm at array.prototype.move.
I had fairly good success with this function:
function array_move(arr, old_index, new_index) {
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing
};
// returns [2, 1, 3]
console.log(array_move([1, 2, 3], 0, 1));
Note that the last return is simply for testing purposes: splice performs operations on the array in-place, so a return is not necessary. By extension, this move is an in-place operation. If you want to avoid that and return a copy, use slice.
Stepping through the code:
- If
new_indexis greater than the length of the array, we want (I presume) to pad the array properly with newundefineds. This little snippet handles this by pushingundefinedon the array until we have the proper length. - Then, in
arr.splice(old_index, 1)[0], we splice out the old element.splicereturns the element that was spliced out, but it's in an array. In our above example, this was[1]. So we take the first index of that array to get the raw1there. - Then we use
spliceto insert this element in the new_index's place. Since we padded the array above ifnew_index > arr.length, it will probably appear in the right place, unless they've done something strange like pass in a negative number.
A fancier version to account for negative indices:
function array_move(arr, old_index, new_index) {
while (old_index < 0) {
old_index += arr.length;
}
while (new_index < 0) {
new_index += arr.length;
}
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing purposes
};
// returns [1, 3, 2]
console.log(array_move([1, 2, 3], -1, -2));
Which should account for things like array_move([1, 2, 3], -1, -2) properly (move the last element to the second to last place). Result for that should be [1, 3, 2].
Either way, in your original question, you would do array_move(arr, 0, 2) for a after c. For d before b, you would do array_move(arr, 3, 1).
I like this method as it's concise and it just works.
function arraymove(arr, fromIndex, toIndex) {
var element = arr[fromIndex];
arr.splice(fromIndex, 1);
arr.splice(toIndex, 0, element);
}
Note: always remember to check your array bounds.
The following snippet prints a few tests in console to show all combinations of fromIndex and toIndex (0..n, 0..n) work.
Run Snippet in jsFiddle
You could subtract one from the index and add the lenght to prevent negative values, get the reaminder with the length and take it as index for the element for mapping.
function shift(arr) {
return arr.map((_, i, a) => a[(i + a.length - 1) % a.length]);
}
const b = [{ value: "" }, 8, "left"];
console.log(shift(b));
map may not be the most appropriate here, but if you insist,
let arr = [{value: ""}, 8, "left"];
let shifted = arr.map((_, i, a) => a[(i + 1) % a.length]);
console.log(shifted);
array1 = array1.concat(array1.splice(0,3));
run the following in Firebug to verify
var array1 = ["t0","t1","t2","t3","t4","t5"];
console.log(array1);
array1 = array1.concat(array1.splice(0,3));
console.log(array1);
results in
["t0", "t1", "t2", "t3", "t4", "t5"]
["t3", "t4", "t5", "t0", "t1", "t2"]
You can slice the array and then join it in reversed order:
var array2 = array1.slice(3).concat(array1.slice(0, 3));