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

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

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

还是c右边的a ?

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

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

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


当前回答

我们可以用多种方法将数组元素从一个位置移动到另一个位置。这里我用三种方法来解决这个问题。

使用拼接移动数组元素,其中时间复杂度为二次time - O(n^2)

function arrayMove(arr, oldIndex, newIndex) {
  const copiedArr = [...arr];
  const length = copiedArr.length;
  
  if (oldIndex !== newIndex && length > oldIndex && length > newIndex) {
    copiedArr.splice(newIndex, 0, copiedArr.splice(oldIndex, 1)[0]);
  }
  
  return copiedArr;
}

arrayMove([1,2,3,4], 0, 3) // [2,3,4,1]

使用flatMap移动数组元素,其中时间复杂度为线性时间- O(n)

function arrayMove(arr, oldIndex, newIndex) {
    const length = arr.length;
    const itemToMove = arr[oldIndex]

    if (oldIndex === newIndex || oldIndex > length || newIndex > length) {
        return arr;
    }

    return arr.flatMap((item, index) => {
        if (index === oldIndex) return [];
        if (index === newIndex) return oldIndex < newIndex ? [item, itemToMove] : [itemToMove, item];
        return item;
    })
}

arrayMove([1,2,3,4], 0, 3) // [2,3,4,1]

当时间复杂度为线性时间- O(n)时,使用reduce方法移动数组元素

function arrayMove(arr, oldIndex, newIndex) {
    const length = arr.length;
    const itemToMove = arr[oldIndex]

    if (oldIndex === newIndex || oldIndex > length || newIndex > length) {
        return arr;
    }

    return arr.reduce((acc, item, index) => {
        if (index === oldIndex) return acc;
        if (index === newIndex) return oldIndex < newIndex ? [...acc, item, itemToMove] : [...acc, itemToMove, item];
        return [...acc, item];
    }, [])
}

arrayMove([1,2,3,4], 0, 3) // [2,3,4,1]

您还可以检查以下要点:将数组元素从一个数组位置移动到另一个数组位置

其他回答

让奥尔迪,新维,阿尔; 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(); } }

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

在2022年,这个typescript实用程序将与单元测试一起工作。

export const arrayMove = <T>(arr: T[], fromIndex: number, toIndex: number) => {
  const newArr = [...arr];
  newArr.splice(toIndex, 0, newArr.splice(fromIndex, 1)[0]);
  return newArr;
};

const testArray = ['1', '2', '3', '4']; description ('arrayMove', () => { it('应该将数组项移动到toIndex', () => { expect(arrayMove(testArray, 2,0))。toEqual(['3', '1', '2', '4']); expect(arrayMove(testArray, 3,1))。toEqual(['1', '4', '2', '3']); expect(arrayMove(testArray, 1,2))。toEqual(['1', '3', '2', '4']); expect(arrayMove(testArray, 0,2))。toEqual(['2', '3', '1', '4']); }); });

该方法将保留原始数组,并检查边界错误。

const move = (from, to, arr) => {
    to = Math.max(to,0)
    from > to 
        ? [].concat(
            arr.slice(0,to), 
            arr[from], 
            arr.filter((x,i) => i != from).slice(to)) 
        : to > from
            ? [].concat(
                arr.slice(0, from), 
                arr.slice(from + 1, to + 1), 
                arr[from], 
                arr.slice(to + 1))
            : arr}

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

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

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