Mark Brown - 2 years ago 172
Javascript Question

# Move an array element from one array position to another

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.

I had fairly good success with this function:

``````Array.prototype.move = function (old_index, new_index) {
if (new_index >= this.length) {
var k = new_index - this.length;
while ((k--) + 1) {
this.push(undefined);
}
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};
``````

Example code: `[1, 2, 3].move(0, 1)` gives `[2, 1, 3]`.

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:

1. 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.
2. Then, in `this.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.
3. Then we use `splice` to insert this element in the new_index's place. Since we padded the array above if `new_index > this.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:

``````Array.prototype.move = 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) {
var k = new_index - this.length;
while ((k--) + 1) {
this.push(undefined);
}
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};
``````

Which should account for things like `[1, 2, 3, 4, 5].move(-1, -2)` properly (move the last element to the second to last place). Result for that should be `[1, 2, 3, 5, 4]`.

Either way, in your original question, you would do `arr.move(0, 2)` for `a` after `c`. For `d` before `b`, you would do `arr.move(3, 1)`.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download