It's hard for me to figure out how to move array elements. For example, the following is given:
var arr = [ 'a', 'b', 'c', 'd', 'e'];
Why can I write 'b' before the mobile function 'd'?
Or 'c' after 'a'?
After the move, the indexes of the remaining elements should be updated. This means that in the first example, after moving, arr [0] ='a ', arr [1] ='d'arr [2] ='b', arr [3] ='c ', arr [4] ='e'
It should look simple, but I can't wrap it.
#1 building
You can implement some basic calculus and create generic functions to move array elements from one location to another.
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; }
See "moving array elements" in "building blocks" for a detailed description.
http://www.gloommatter.com/DDesign/programming/moving-any-array-elements-universal-function.html
#2 building
Array.move.js
abstract
Moves an element in an array, returning the array containing the moved element.
syntax
array.move(index, howMany, toIndex);
parameter
Index: index of element movement. If negative, the index starts at the end.
howMany: the number of elements to move from the index.
toIndex: index of the array where the moving element is placed. If negative, toIndex starts at 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; } });
#3 building
Finally, I combine these two methods, and the effect is better when I move long distance or short distance. I got pretty consistent results, but it could be adjusted by someone smarter than me to do different jobs for different sizes, and so on.
When moving objects at a small distance, some other methods are much faster than splicing (x10). However, this may vary depending on the length of the array, but it does 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
#4 building
The splice () method adds / removes items from the array and returns the deleted items.
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"]
Because the function is Linkable, So it can also work:
alert(arr.move(0,2).join(','));
#5 building
My 2c. Easy to read, efficient, fast, no new arrays will be created.
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; }