## The Question :

*576 people think this question is useful*

I’m having a hard time figuring out how to move an array element. For example, given the following:

var arr = [ 'a', 'b', 'c', 'd', 'e'];

How can I write a function to move `'d'`

before `'b'`

?

Or `'a'`

after `'c'`

?

After the move, the indices of the rest of the elements should be updated. This means in the first example after the move arr[0] would = ‘a’, arr[1] = ‘d’ arr[2] = ‘b’, arr[3] = ‘c’, arr[4] = ‘e’

This seems like it should be pretty simple, but I can’t wrap my head around it.

*The Question Comments :*

## The Answer 1

*724 people think this answer is useful*

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_index`

is greater than the length of the array, we want (I presume) to pad the array properly with new `undefined`

s. This little snippet handles this by pushing `undefined`

on the array until we have the proper length.
- Then, in
`arr.splice(old_index, 1)[0]`

, we splice out the old element. `splice`

returns 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 raw `1`

there.
- Then we use
`splice`

to insert this element in the new_index’s place. Since we padded the array above if `new_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)`

.

## The Answer 2

*291 people think this answer is useful*

Here’s a one liner I found on JSPerf….

Array.prototype.move = function(from, to) {
this.splice(to, 0, this.splice(from, 1)[0]);
};

which is awesome to read, but if you want performance (in small data sets) try…

Array.prototype.move2 = function(pos1, pos2) {
// local variables
var i, tmp;
// cast input parameters to integers
pos1 = parseInt(pos1, 10);
pos2 = parseInt(pos2, 10);
// if positions are different and inside array
if (pos1 !== pos2 && 0 <= pos1 && pos1 <= this.length && 0 <= pos2 && pos2 <= this.length) {
// save element from position 1
tmp = this[pos1];
// move element down and shift other elements up
if (pos1 < pos2) {
for (i = pos1; i < pos2; i++) {
this[i] = this[i + 1];
}
}
// move element up and shift other elements down
else {
for (i = pos1; i > pos2; i--) {
this[i] = this[i - 1];
}
}
// put element from position 1 to destination
this[pos2] = tmp;
}
}

I can’t take any credit, it should all go to Richard Scarrott. It beats the splice based method for smaller data sets in this performance test. It is however significantly slower on larger data sets as Darwayne points out.

## The Answer 3

*267 people think this answer is useful*

I like this way. It’s concise and it 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.

Run Snippet in jsFiddle

## The Answer 4

*37 people think this answer is useful*

The splice() method adds/removes items to/from an array, and returns the **removed** item(s).

Note: This method changes the original array. /w3schools/

Array.prototype.move = function(from,to){
this.splice(to,0,this.splice(from,1)[0]);
return this;
};
var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(3,1);//["a", "d", "b", "c", "e"]
var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(0,2);//["b", "c", "a", "d", "e"]

as the function is chainable this works too:

alert(arr.move(0,2).join(','));

demo here

## The Answer 5

*28 people think this answer is useful*

My 2c. Easy to read, it works, it’s fast, it doesn’t create new arrays.

function move(array, from, to) {
if( to === from ) return array;
var target = array[from];
var increment = to < from ? -1 : 1;
for(var k = from; k != to; k += increment){
array[k] = array[k + increment];
}
array[to] = target;
return array;
}

## The Answer 6

*19 people think this answer is useful*

Got this idea from @Reid of pushing something in the place of the item that is supposed to be moved to keep the array size constant. That does simplify calculations. Also, pushing an empty object has the added benefits of being able to search for it uniquely later on. This works because two objects are not equal until they are referring to the same object.

({}) == ({}); // false

So here’s the function which takes in the source array, and the source, destination indexes. You could add it to the Array.prototype if needed.

function moveObjectAtIndex(array, sourceIndex, destIndex) {
var placeholder = {};
// remove the object from its initial position and
// plant the placeholder object in its place to
// keep the array length constant
var objectToMove = array.splice(sourceIndex, 1, placeholder)[0];
// place the object in the desired position
array.splice(destIndex, 0, objectToMove);
// take out the temporary object
array.splice(array.indexOf(placeholder), 1);
}

## The Answer 7

*16 people think this answer is useful*

This is based on @Reid’s solution. Except:

- I’m not changing the
`Array`

prototype.
- Moving an item out of bounds to the right does not create
`undefined`

items, it just moves the item to the right-most position.

Function:

function move(array, oldIndex, newIndex) {
if (newIndex >= array.length) {
newIndex = array.length - 1;
}
array.splice(newIndex, 0, array.splice(oldIndex, 1)[0]);
return array;
}

Unit tests:

describe('ArrayHelper', function () {
it('Move right', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 0, 1);
assert.equal(array[0], 2);
assert.equal(array[1], 1);
assert.equal(array[2], 3);
})
it('Move left', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 1, 0);
assert.equal(array[0], 2);
assert.equal(array[1], 1);
assert.equal(array[2], 3);
});
it('Move out of bounds to the left', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 1, -2);
assert.equal(array[0], 2);
assert.equal(array[1], 1);
assert.equal(array[2], 3);
});
it('Move out of bounds to the right', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 1, 4);
assert.equal(array[0], 1);
assert.equal(array[1], 3);
assert.equal(array[2], 2);
});
});

## The Answer 8

*11 people think this answer is useful*

Here is my **one liner ES6 solution** with an optional parameter `on`

.

if (typeof Array.prototype.move === "undefined") {
Array.prototype.move = function(from, to, on = 1) {
this.splice(to, 0, ...this.splice(from, on))
}
}

*Adaptation of the first solution proposed by *`digiguru`

The parameter `on`

is the number of element starting from `from`

you want to move.

## The Answer 9

*8 people think this answer is useful*

I’ve implemented an immutable `ECMAScript 6`

solution based off of `@Merc`

‘s answer over here:

const moveItemInArrayFromIndexToIndex = (array, fromIndex, toIndex) => {
if (fromIndex === toIndex) return array;
const newArray = [...array];
const target = newArray[fromIndex];
const inc = toIndex < fromIndex ? -1 : 1;
for (let i = fromIndex; i !== toIndex; i += inc) {
newArray[i] = newArray[i + inc];
}
newArray[toIndex] = target;
return newArray;
};

The variable names can be shortened, just used long ones so that the code can explain itself.

## The Answer 10

*7 people think this answer is useful*

The `splice`

method of `Array`

might help: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice

Just keep in mind it might be relatively expensive since it has to actively re-index the array.

## The Answer 11

*7 people think this answer is useful*

One approach would be to create a new array with the pieces in the order you want, using the slice method.

Example

var arr = [ 'a', 'b', 'c', 'd', 'e'];
var arr2 = arr.slice(0,1).concat( ['d'] ).concat( arr.slice(2,4) ).concat( arr.slice(4) );

- arr.slice(0,1) gives you [‘a’]
- arr.slice(2,4) gives you [‘b’, ‘c’]
- arr.slice(4) gives you [‘e’]

## The Answer 12

*6 people think this answer is useful*

You can implement some basic Calculus and create a universal function for moving array element from one position to the other.

For JavaScript it looks like this:

function magicFunction (targetArray, indexFrom, indexTo) {
targetElement = targetArray[indexFrom];
magicIncrement = (indexTo - indexFrom) / Math.abs (indexTo - indexFrom);
for (Element = indexFrom; Element != indexTo; Element += magicIncrement){
targetArray[Element] = targetArray[Element + magicIncrement];
}
targetArray[indexTo] = targetElement;
}

Check out “moving array elements” at “gloommatter” for detailed explanation.

http://www.gloommatter.com/DDesign/programming/moving-any-array-elements-universal-function.html

## The Answer 13

*5 people think this answer is useful*

I needed an immutable move method (one that didn’t change the original array), so I adapted @Reid’s accepted answer to simply use Object.assign to create a copy of the array before doing the splice.

Array.prototype.immutableMove = function (old_index, new_index) {
var copy = Object.assign([], this);
if (new_index >= copy.length) {
var k = new_index - copy.length;
while ((k--) + 1) {
copy.push(undefined);
}
}
copy.splice(new_index, 0, copy.splice(old_index, 1)[0]);
return copy;
};

Here is a jsfiddle showing it in action.

## The Answer 14

*4 people think this answer is useful*

Array.prototype.moveUp = function (value, by) {
var index = this.indexOf(value),
newPos = index - (by || 1);
if (index === -1)
throw new Error("Element not found in array");
if (newPos < 0)
newPos = 0;
this.splice(index, 1);
this.splice(newPos, 0, value);
};
Array.prototype.moveDown = function (value, by) {
var index = this.indexOf(value),
newPos = index + (by || 1);
if (index === -1)
throw new Error("Element not found in array");
if (newPos >= this.length)
newPos = this.length;
this.splice(index, 1);
this.splice(newPos, 0, value);
};
var arr = ['banana', 'curyWurst', 'pc', 'remembaHaruMembaru'];
alert('withiout changes= '+arr[0]+' ||| '+arr[1]+' ||| '+arr[2]+' ||| '+arr[3]);
arr.moveDown(arr[2]);
alert('third word moved down= '+arr[0] + ' ||| ' + arr[1] + ' ||| ' + arr[2] + ' ||| ' + arr[3]);
arr.moveUp(arr[2]);
alert('third word moved up= '+arr[0] + ' ||| ' + arr[1] + ' ||| ' + arr[2] + ' ||| ' + arr[3]);

http://plnkr.co/edit/JaiAaO7FQcdPGPY6G337?p=preview

## The Answer 15

*4 people think this answer is useful*

Another pure JS variant using ES6 array spread operator with no mutation

const reorder = (array, sourceIndex, destinationIndex) => {
const smallerIndex = Math.min(sourceIndex, destinationIndex);
const largerIndex = Math.max(sourceIndex, destinationIndex);
return [
...array.slice(0, smallerIndex),
...(sourceIndex < destinationIndex
? array.slice(smallerIndex + 1, largerIndex + 1)
: []),
array[sourceIndex],
...(sourceIndex > destinationIndex
? array.slice(smallerIndex, largerIndex)
: []),
...array.slice(largerIndex + 1),
];
}
// returns ['a', 'c', 'd', 'e', 'b', 'f']
console.log(reorder(['a', 'b', 'c', 'd', 'e', 'f'], 1, 4))

## The Answer 16

*2 people think this answer is useful*

I ended up combining two of these to work a little better when moving both small and large distances. I get fairly consistent results, but this could probably be tweaked a little bit by someone smarter than me to work differently for different sizes, etc.

Using some of the other methods when moving objects small distances was significantly faster (x10) than using splice. This might change depending on the array lengths though, but it is true for large arrays.

function ArrayMove(array, from, to) {
if ( Math.abs(from - to) > 60) {
array.splice(to, 0, array.splice(from, 1)[0]);
} else {
// works better when we are not moving things very far
var target = array[from];
var inc = (to - from) / Math.abs(to - from);
var current = from;
for (; current != to; current += inc) {
array[current] = array[current + inc];
}
array[to] = target;
}
}

http://jsperf.com/arraymove-many-sizes

## The Answer 17

*2 people think this answer is useful*

It is stated in many places (adding custom functions into Array.prototype) playing with the Array prototype could be a bad idea, anyway I combined the best from various posts, I came with this, using modern Javascript:

Object.defineProperty(Array.prototype, 'immutableMove', {
enumerable: false,
value: function (old_index, new_index) {
var copy = Object.assign([], this)
if (new_index >= copy.length) {
var k = new_index - copy.length;
while ((k--) + 1) { copy.push(undefined); }
}
copy.splice(new_index, 0, copy.splice(old_index, 1)[0]);
return copy
}
});
//how to use it
myArray=[0, 1, 2, 3, 4];
myArray=myArray.immutableMove(2, 4);
console.log(myArray);
//result: 0, 1, 3, 4, 2

Hope can be useful to anyone

## The Answer 18

*2 people think this answer is useful*

This version isn’t ideal for all purposes, and not everyone likes comma expressions, but here’s a one-liner that’s a pure expression, creating a fresh copy:

const move = (from, to, ...a) => (a.splice(to, 0, ...a.splice(from, 1)), a)

A slightly performance-improved version returns the input array if no move is needed, it’s still OK for immutable use, as the array won’t change, and it’s still a pure expression:

const move = (from, to, ...a) =>
from === to
? a
: (a.splice(to, 0, ...a.splice(from, 1)), a)

The invocation of either is

const shuffled = move(fromIndex, toIndex, ...list)

i.e. it relies on spreading to generate a fresh copy. Using a fixed arity 3 `move`

would jeopardize either the single expression property, or the non-destructive nature, or the performance benefit of `splice`

. Again, it’s more of an example that meets some criteria than a suggestion for production use.

## The Answer 19

*1 people think this answer is useful*

# Array.move.js

## Summary

Moves elements within an array, returning an array containing the moved elements.

## Syntax

array.move(index, howMany, toIndex);

## Parameters

**index**: Index at which to move elements. If negative, **index** will start from the end.

**howMany**: Number of elements to move from **index**.

**toIndex**: Index of the array at which to place the moved elements. If negative, **toIndex** will start from the end.

## Usage

array = ["a", "b", "c", "d", "e", "f", "g"];
array.move(3, 2, 1); // returns ["d","e"]
array; // returns ["a", "d", "e", "b", "c", "f", "g"]

## Polyfill

Array.prototype.move || Object.defineProperty(Array.prototype, "move", {
value: function (index, howMany, toIndex) {
var
array = this,
index = parseInt(index) || 0,
index = index < 0 ? array.length + index : index,
toIndex = parseInt(toIndex) || 0,
toIndex = toIndex < 0 ? array.length + toIndex : toIndex,
toIndex = toIndex <= index ? toIndex : toIndex <= index + howMany ? index : toIndex - howMany,
moved;
array.splice.apply(array, [toIndex, 0].concat(moved = array.splice(index, howMany)));
return moved;
}
});

## The Answer 20

*1 people think this answer is useful*

I used the nice answer of @Reid, but struggled with moving an element from the end of an array one step further – to the beginning (like in a **loop**).
E.g. [‘a’, ‘b’, ‘c’] should become [‘c’, ‘a’, ‘b’] by calling .move(2,3)

I achieved this by changing the case for new_index >= this.length.

Array.prototype.move = function (old_index, new_index) {
console.log(old_index + " " + new_index);
while (old_index < 0) {
old_index += this.length;
}
while (new_index < 0) {
new_index += this.length;
}
if (new_index >= this.length) {
new_index = new_index % this.length;
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};

## The Answer 21

*1 people think this answer is useful*

As an addition to Reid’s excellent answer (and because I cannot comment);
You can use modulo to make both negative indices and too large indices “roll over”:

function array_move(arr, old_index, new_index) {
new_index =((new_index % arr.length) + arr.length) % arr.length;
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));

## The Answer 22

*1 people think this answer is useful*

let ar = ['a', 'b', 'c', 'd'];
function change( old_array, old_index , new_index ){
return old_array.map(( item , index, array )=>{
if( index === old_index ) return array[ new_index ];
else if( index === new_index ) return array[ old_index ];
else return item;
});
}
let result = change( ar, 0, 1 );
console.log( result );

result:

["b", "a", "c", "d"]

## The Answer 23

*1 people think this answer is useful*

const move = (from, to, ...a) =>from === to ? a : (a.splice(to, 0, ...a.splice(from, 1)), a);
const moved = move(0, 2, ...['a', 'b', 'c']);
console.log(moved)

## The Answer 24

*1 people think this answer is useful*

I thought this was a swap problem but it’s not. Here’s my one-liner solution:

const move = (arr, from, to) => arr.map((item, i) => i === to ? arr[from] : (i >= Math.min(from, to) && i <= Math.max(from, to) ? arr[i + Math.sign(to - from)] : item));

Here’s a small test:

let test = ['a', 'b', 'c', 'd', 'e'];
console.log(move(test, 0, 2)); // [ 'b', 'c', 'a', 'd', 'e' ]
console.log(move(test, 1, 3)); // [ 'a', 'c', 'd', 'b', 'e' ]
console.log(move(test, 2, 4)); // [ 'a', 'b', 'd', 'e', 'c' ]
console.log(move(test, 2, 0)); // [ 'c', 'a', 'b', 'd', 'e' ]
console.log(move(test, 3, 1)); // [ 'a', 'd', 'b', 'c', 'e' ]
console.log(move(test, 4, 2)); // [ 'a', 'b', 'e', 'c', 'd' ]
console.log(move(test, 4, 0)); // [ 'e', 'a', 'b', 'c', 'd' ]

## The Answer 25

*1 people think this answer is useful*

This is a really simple method using splice

Array.prototype.moveToStart = function(index) {
this.splice(0, 0, this.splice(index, 1)[0]);
return this;
};

## The Answer 26

*1 people think this answer is useful*

Here’s one way to do it. It handles negative numbers as well as an added bonus.

const numbers = [1, 2, 3];
const moveElement = (array, from, to) => {
const copy = [...array];
const valueToMove = copy.splice(from, 1)[0];
copy.splice(to, 0, valueToMove);
return copy;
};
console.log(moveElement(numbers, 0, 2))
// > [2, 3, 1]
console.log(moveElement(numbers, -1, -3))
// > [3, 1, 2]

## The Answer 27

*0 people think this answer is useful*

let oldi, newi, arr;
if(newi !== oldi) {
let el = this.arr.splice(oldi, 1);
if(newi > oldi && newi === (this.arr.length + 2)) {
this.arr.push("");
}
this.arr.splice(newi, 0, el);
if(newi > oldi && newi === (this.arr.length + 2)) {
this.arr.pop();
}
}

## The Answer 28

*0 people think this answer is useful*

var ELEMS = ['a', 'b', 'c', 'd', 'e'];
/*
Source item will remove and it will be placed just after destination
*/
function moveItemTo(sourceItem, destItem, elements) {
var sourceIndex = elements.indexOf(sourceItem);
var destIndex = elements.indexOf(destItem);
if (sourceIndex >= -1 && destIndex > -1) {
elements.splice(destIndex, 0, elements.splice(sourceIndex, 1)[0]);
}
return elements;
}
console.log('Init: ', ELEMS);
var result = moveItemTo('a', 'c', ELEMS);
console.log('BeforeAfter: ', result);

## The Answer 29

*0 people think this answer is useful*

Immutable version without array copy:

const moveInArray = (arr, fromIndex, toIndex) => {
if (toIndex === fromIndex || toIndex >= arr.length) return arr;
const toMove = arr[fromIndex];
const movedForward = fromIndex < toIndex;
return arr.reduce((res, next, index) => {
if (index === fromIndex) return res;
if (index === toIndex) return res.concat(
movedForward ? [next, toMove] : [toMove, next]
);
return res.concat(next);
}, []);
};

## The Answer 30

*0 people think this answer is useful*

I think the best way is define a new property for Arrays

Object.defineProperty(Array.prototype, 'move', {
value: function (old_index, new_index) {
while (old_index < 0) {
old_index += this.length;
}
while (new_index < 0) {
new_index += this.length;
}
if (new_index >= this.length) {
let k = new_index - this.length;
while ((k--) + 1) {
this.push(undefined);
}
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this;
}
});
console.log([10, 20, 30, 40, 50].move(0, 1)); // [20, 10, 30, 40, 50]
console.log([10, 20, 30, 40, 50].move(0, 2)); // [20, 30, 10, 40, 50]