我很难弄清楚如何移动数组中的一个元素。例如,给定以下条件:

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

我怎么能写一个函数来移动元素'd'到'b'的左边?

还是c右边的a ?

移动元素之后,应该更新其余元素的索引。结果数组将是:

array = ['a', 'd', 'b', 'c', 'e']

这看起来应该很简单,但我无法理解它。


当前回答

我认为最好的方法是为数组定义一个新属性

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]

其他回答

在很多地方都说过(在Array.prototype中添加自定义函数)使用Array原型可能是一个坏主意,无论如何我结合了来自各种帖子的最佳内容,我使用现代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

希望对任何人都是有用的

您可以实现一些基本的演算,并创建一个通用函数来将数组元素从一个位置移动到另一个位置。

对于JavaScript,它看起来是这样的:

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; 

}

查看“移动数组元素”在“忧郁”的详细解释。

https://web.archive.org/web/20121105042534/http://www.gloommatter.com:80/DDesign/programming/moving-any-array-elements-universal-function.html

splice()方法的作用是:向数组中添加/从数组中删除项,并返回已删除的项。 注意:该方法会改变原始数组。/ 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"]

由于函数是可链的,这也工作:

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

演示

我认为最好的方法是为数组定义一个新属性

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]

下面是我的一行ES6解决方案,带有一个可选参数。

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

digiguru提出的第一个解决方案的改编

on的参数是你想要移动的元素个数。

这里有一个可链接的变化:

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

[3, 4, 5, 1, 2].move(3, 0, 2) // => [1, 2, 3, 4, 5]

如果你想避免原型污染,这里有一个独立的函数:

function move(array, from, to, on = 1) {
  return array.splice(to, 0, ...array.splice(from, on)), array
}

move([3, 4, 5, 1, 2], 3, 0, 2) // => [1, 2, 3, 4, 5]

最后,这是一个不会改变原始数组的纯函数:

function moved(array, from, to, on = 1) {
  return array = array.slice(), array.splice(to, 0, ...array.splice(from, on)), array
}

这应该涵盖了其他答案中出现的所有变化。