将数组元素从一个数组位置移动到另一个数组位置

2022-08-29 22:33:46

我很难弄清楚如何移动数组的元素。例如,给定以下内容:

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

如何编写一个函数将元素移动到 ?'d''b'

还是在 ?'a''c'

移动元素后,应更新其余元素的索引。生成的数组将为:

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

这似乎应该很简单,但我不能把我的头缠绕在它上面。


答案 1

如果你想要一个npm上的版本,array-move是最接近这个答案的,尽管它不是相同的实现。有关更多详细信息,请参阅其用法部分。这个答案的以前版本(修改后的Array.prototype.move)可以在npm的array.prototype.move上找到。


我在这个功能上取得了相当大的成功:

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)); 

请注意,最后一个仅用于测试目的:拼接就地对数组执行操作,因此不需要返回。推而广之,这是一个就地操作。如果要避免这种情况并返回副本,请使用切片returnmove

单步执行代码:

  1. 如果 大于数组的长度,我们希望(我推测)用新的 s 正确填充数组。这个小片段通过推动数组来处理这个问题,直到我们有适当的长度。new_indexundefinedundefined
  2. 然后,在 中,我们拼接出旧元素。 返回已拼接出来但位于数组中的元素。在上面的示例中,这是 。因此,我们获取该数组的第一个索引来获取原始值。arr.splice(old_index, 1)[0]splice[1]1
  3. 然后,我们用于将此元素插入new_index的位置。由于我们填充了上面的数组 if ,它可能会出现在正确的位置,除非他们做了一些奇怪的事情,比如在负数中传递。splicenew_index > arr.length

一个更花哨的版本来解释负面指数:

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));

这应该正确考虑诸如此类的事情(将最后一个元素移动到倒数第二个位置)。结果应该是 。array_move([1, 2, 3], -1, -2)[1, 3, 2]

无论哪种方式,在你最初的问题中,你都会在之后做。对于之前,你会做的。array_move(arr, 0, 2)acdbarray_move(arr, 3, 1)


答案 2

我喜欢这种方式。它简洁明了,而且有效。

function arraymove(arr, fromIndex, toIndex) {
    var element = arr[fromIndex];
    arr.splice(fromIndex, 1);
    arr.splice(toIndex, 0, element);
}

注意:始终记得检查数组边界。

在 jsFiddle 中运行代码段