我很难弄清楚如何移动数组中的一个元素。例如,给定以下条件:
var array = [ 'a', 'b', 'c', 'd', 'e'];
我怎么能写一个函数来移动元素'd'到'b'的左边?
还是c右边的a ?
移动元素之后,应该更新其余元素的索引。结果数组将是:
array = ['a', 'd', 'b', 'c', 'e']
这看起来应该很简单,但我无法理解它。
我很难弄清楚如何移动数组中的一个元素。例如,给定以下条件:
var array = [ 'a', 'b', 'c', 'd', 'e'];
我怎么能写一个函数来移动元素'd'到'b'的左边?
还是c右边的a ?
移动元素之后,应该更新其余元素的索引。结果数组将是:
array = ['a', 'd', 'b', 'c', 'e']
这看起来应该很简单,但我无法理解它。
当前回答
我使用了@Reid这个不错的答案,但是很难将一个元素从数组的末尾移动到开头(就像在循环中一样)。 例如[a, b, c的)应该成为[' c ', ' ', ' b ']通过调用.move(2、3)
我通过改变new_index >= this.length来实现这一点。
Array.prototype.move = function (old_index, new_index) {
console.log(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) {
new_index = new_index % this.length;
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};
其他回答
另一个纯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))
我们可以用多种方法将数组元素从一个位置移动到另一个位置。这里我用三种方法来解决这个问题。
使用拼接移动数组元素,其中时间复杂度为二次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]
您还可以检查以下要点:将数组元素从一个数组位置移动到另一个数组位置
您可以实现一些基本的演算,并创建一个通用函数来将数组元素从一个位置移动到另一个位置。
对于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
Array的splice方法可能有帮助:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice
请记住,它可能相对昂贵,因为它必须主动重新索引数组。
我需要一个不可变的移动方法(一个不改变原始数组的方法),所以我改编了@Reid的接受的答案,简单地使用对象。赋值以在进行拼接之前创建数组的副本。
Array.prototype.immutableMove = 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;
};
下面是一个jsfiddle演示它的运行。