我很难弄清楚如何移动数组中的一个元素。例如,给定以下条件:
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']
这看起来应该很简单,但我无法理解它。
当前回答
我们可以用多种方法将数组元素从一个位置移动到另一个位置。这里我用三种方法来解决这个问题。
使用拼接移动数组元素,其中时间复杂度为二次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]
您还可以检查以下要点:将数组元素从一个数组位置移动到另一个数组位置
其他回答
如果对象是嵌套的:
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)
一种方法是使用slice方法,按照您想要的顺序创建一个包含片段的新数组。
例子
var arr = [ 'a', 'b', 'c', 'd', 'e'];
var arr2 = arr.slice(0,1).concat( ['d'] ).concat( arr.slice(2,4) ).concat( arr.slice(4) );
Arr.slice(0,1)得到['a'] Arr.slice(2,4)给出['b', 'c'] Arr.slice(4)给出['e']
打印稿版本
摘自@Merc的回答。我最喜欢这个,因为它没有创建新的数组,而是在适当的地方修改数组。我所做的只是更新到ES6并添加类型。
export function moveItemInArray<T>(workArray: T[], fromIndex: number, toIndex: number): T[] {
if (toIndex === fromIndex) {
return workArray;
}
const target = workArray[fromIndex];
const increment = toIndex < fromIndex ? -1 : 1;
for (let k = fromIndex; k !== toIndex; k += increment) {
workArray[k] = workArray[k + increment];
}
workArray[toIndex] = target;
return workArray;
}
面向对象,可表达,可调试,无突变,已测试。
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);
});
splice()方法的作用是:向数组中添加/从数组中删除项,并返回已删除的项。 注意:该方法会改变原始数组。/ w3schools /
Array.prototype.move = function(from,to){
this.splice(to,0,this.splice(from,1)[0]);
return this;
};
var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(3,1);//["a", "d", "b", "c", "e"]
var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(0,2);//["b", "c", "a", "d", "e"]
由于函数是可链的,这也工作:
alert(arr.move(0,2).join(','));
演示