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

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

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

还是c右边的a ?

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

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

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


当前回答

如果对象是嵌套的:

  let array = ['a', 'b', 'c', 'd', 'e'];
  let existingElement = JSON.parse(JSON.stringify(array[3]));
  array.splice(1, 0, existingElement);
  array.splice(4, 1);
  console.log(array)

其他回答

找到并移动一个元素从第n个位置到第0个位置。

找到并移动“d”到第0个位置:

let arr = [ 'a', 'b', 'c', 'd', 'e'];
arr = [...arr.filter(item => item === 'd'), ...arr.filter(item => item !== 'd')];

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

Array.move.js

总结

移动数组中的元素,返回包含已移动元素的数组。

语法

array.move(index, howMany, toIndex);

参数

index:移动元素所在的索引。如果是负数,指数将从末尾开始。

howMany:要从索引中移动的元素数量。

toIndex:移动元素所在数组的索引。如果为负,则toIndex将从末尾开始。

使用

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

在你的例子中,因为是一个字符串数组,我们可以使用一个ranking对象来重新排列字符串数组:

let rank =  { 'a': 0, 'b': 1, 'c': 2, 'd': 0.5, 'e': 4 };
arr.sort( (i, j) => rank[i] - rank[j] );

我们可以使用这种方法来编写一个move函数,它工作在字符串数组上:

函数stringArrayMove(from, to) { 令rank = arr。Reduce ((p, c, i) => (p [c] = i, p), ({})); / /等级= {a: 0,“b”:1、“c”:2,' d ': 3,“e”:4} Rank [arr[from]] = - 0.5; / /等级= {a: 0,“b”:1、“c”:2,' d ': 1.5,“e”:4} 加勒比海盗。排序((i, j) => rank[i] - rank[j]); // arr = ['a', 'd', 'b', 'c', 'e']; } Let arr = ['a', 'b', 'c', 'd', 'e']; stringArrayMove(arr, 3,1); console.log(JSON.stringify(arr));

然而,如果我们想要排序的是一个对象数组,我们可以将排序作为每个对象的新属性,即。

let arr = [ { value: 'a', rank: 0 },
            { value: 'b', rank: 1 },
            { value: 'c', rank: 2 },
            { value: 'd', rank: 0.5 },
            { value: 'e', rank: 4 } ];
arr.sort( (i, j) => i['rank'] - j['rank'] );

我们可以使用Symbol来隐藏这个属性的可见性,即它不会在JSON.stringify中显示。我们可以在objectArrayMove函数中泛化它:

function objectArrayMove(arr, from, to) { let rank = Symbol("rank"); arr.forEach( (item, i) => item[rank] = i ); arr[from][rank] = to - 0.5; arr.sort( (i, j) => i[rank] - j[rank]); } let arr = [ { value: 'a' }, { value: 'b' }, { value: 'c' }, { value: 'd' }, { value: 'e' } ]; console.log( 'array before move: ', JSON.stringify( arr ) ); // array before move: [{"value":"a"},{"value":"b"},{"value":"c"},{"value":"d"},{"value":"e"}] objectArrayMove(arr, 3, 1); console.log( 'array after move: ', JSON.stringify( arr ) ); // array after move: [{"value":"a"},{"value":"d"},{"value":"b"},{"value":"c"},{"value":"e"}]

这是基于@Reid的解决方案。除了:

我不会改变数组原型。 向右移动一个项目并不会创建未定义的项目,它只是将项目移动到最右边的位置。

功能:

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

单元测试:

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