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

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

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

还是c右边的a ?

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

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

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


当前回答

让奥尔迪,新维,阿尔; if(newi !== oldi) { let el = this.arr.splice(oldi, 1); if(newi > oldi && newi === (this.arr.length + 2)) { this.arr.push(“”); } this.arr.splice(newi, 0, el); if(newi > oldi && newi === (this.arr.length + 2)) { this.arr.pop(); } }

其他回答

不复制数组的不可变版本:

const moveInArray = (arr, fromIndex, toIndex) => {
  if (toIndex === fromIndex || toIndex >= arr.length) return arr;

  const toMove = arr[fromIndex];
  const movedForward = fromIndex < toIndex;

  return arr.reduce((res, next, index) => {
    if (index === fromIndex) return res;
    if (index === toIndex) return res.concat(
      movedForward ? [next, toMove] : [toMove, next]
    );

    return res.concat(next);
  }, []);
};

如果对象是嵌套的:

  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)

面向对象,可表达,可调试,无突变,已测试。

class Sorter {
    sortItem(array, fromIndex, toIndex) {
        const reduceItems = () => {
            const startingItems = array.slice(0, fromIndex);
            const endingItems = array.slice(fromIndex + 1);
            return startingItems.concat(endingItems);
        }
        const addMovingItem = (movingItem, reducedItems) => {
            const startingNewItems = reducedItems.slice(0, toIndex);
            const endingNewItems = reducedItems.slice(toIndex);
            const newItems = startingNewItems.concat([movingItem]).concat(endingNewItems);
            return newItems;
        }
        const movingItem = array[fromIndex];
        const reducedItems = reduceItems();
        const newItems = addMovingItem(movingItem, reducedItems);
        return newItems;
    }
}

const sorter = new Sorter();
export default sorter;
import sorter from 'src/common/Sorter';

test('sortItem first item forward', () => {
    const startingArray = ['a', 'b', 'c', 'd'];
    const expectedArray = ['b', 'a', 'c', 'd'];
    expect(sorter.sortItem(startingArray, 0, 1)).toStrictEqual(expectedArray);
});
test('sortItem middle item forward', () => {
    const startingArray = ['a', 'b', 'c', 'd'];
    const expectedArray = ['a', 'c', 'b', 'd'];
    expect(sorter.sortItem(startingArray, 1, 2)).toStrictEqual(expectedArray);
});
test('sortItem middle item backward', () => {
    const startingArray = ['a', 'b', 'c', 'd'];
    const expectedArray = ['a', 'c', 'b', 'd'];
    expect(sorter.sortItem(startingArray, 2, 1)).toStrictEqual(expectedArray);
});
test('sortItem last item backward', () => {
    const startingArray = ['a', 'b', 'c', 'd'];
    const expectedArray = ['a', 'b', 'd', 'c'];
    expect(sorter.sortItem(startingArray, 3, 2)).toStrictEqual(expectedArray);
});

另一个纯JS变体使用ES6数组展开运算符,没有突变

const reorder = (array, sourceIndex, destinationIndex) => { const smallerIndex = Math.min(sourceIndex, destinationIndex); const largerIndex = Math.max(sourceIndex, destinationIndex); return [ ...array.slice(0, smallerIndex), ...(sourceIndex < destinationIndex ? array.slice(smallerIndex + 1, largerIndex + 1) : []), array[sourceIndex], ...(sourceIndex > destinationIndex ? array.slice(smallerIndex, largerIndex) : []), ...array.slice(largerIndex + 1), ]; } // returns ['a', 'c', 'd', 'e', 'b', 'f'] console.log(reorder(['a', 'b', 'c', 'd', 'e', 'f'], 1, 4))

我使用不可变性助手库解决了我的问题。

import update from 'immutability-helper';

const move = (arr: any[], from: number, to: number) => update(arr, {
  $splice: [
    [from, 1],
    [to, 0, arr[from] as string],
  ],
});

const testArray = ['a', 'b', 'c', 'd', 'e'];
console.log(move(testArray, 1, 3)); // [ 'c', 'b', 'c', 'd', 'e' ]
console.log(move(testArray, 4, 0)); // [ 'e', 'b', 'c', 'd', 'a' ]