Array.prototype.reverse 可以在原地(通过变异)反转数组的内容...
是否有一种类似简单的策略可以在不改变原始数组内容的情况下反转数组(无变异)?
Array.prototype.reverse 可以在原地(通过变异)反转数组的内容...
是否有一种类似简单的策略可以在不改变原始数组内容的情况下反转数组(无变异)?
跳进2022年,这里是今天最高效的解决方案(性能最佳,且不需要额外的内存使用)。
对于任何ArrayLike
类型,最快速地反转它的方法是逻辑上的,将其包装成一个反转的可迭代对象:
function reverse<T>(input: ArrayLike<T>): Iterable<T> {
return {
[Symbol.iterator](): Iterator<T> {
let i = input.length;
return {
next(): IteratorResult<T> {
return i
? {value: input[--i], done: false}
: {value: undefined, done: true};
},
};
},
};
}
通过这种方式,您可以反向迭代任何 Array
、string
或 Buffer
,而无需进行任何额外的复制或处理来获取反向数据:
for(const a of reverse([1, 2, 3])) {
console.log(a); //=> 3 2 1
}
这是最快的方法,因为您不需要复制数据,也不需要进行任何处理,只需逻辑上反转即可。
为了演示目的而进行原地反转,使用变量交换(但如果您不想改变原始数据,就需要创建一个副本)
const myArr = ["a", "b", "c", "d"];
const copy = [...myArr];
for (let i = 0; i < (copy.length - 1) / 2; i++) {
const lastIndex = copy.length - 1 - i;
[copy[i], copy[lastIndex]] = [copy[lastIndex], copy[i]]
}
有没有类似简单的策略可以在不改变原始数组内容(无突变)的情况下反转数组?
是的,可以通过使用返回应用操作后的新集合的to[Operation]
方法来实现这一点(目前处于第三阶段,即将推出)。
实现方式如下:
const arr = [5, 4, 3, 2, 1];
const reversedArr = arr.toReverse();
console.log(arr); // [5, 4, 3, 2, 1]
console.log(reversedArr); // [1, 2, 3, 4, 5]
Array.prototype.myNonMutableReverse = function () {
const reversedArr = [];
for (let i = this.length - 1; i >= 0; i--) reversedArr.push(this[i]);
return reversedArr;
};
const a = [1, 2, 3, 4, 5, 6, 7, 8];
const b = a.myNonMutableReverse();
console.log("a",a);
console.log("////////")
console.log("b",b);
转换为普通JavaScript:
function reverseArray(arr, num) {
var newArray = [];
for (let i = num; i <= arr.length - 1; i++) {
newArray.push(arr[i]);
}
return newArray;
}
ES6:
const reverseArr = [1,2,3,4].sort(()=>1)
Array.prototype.sort
回调函数(或所谓的“比较函数”)的工作方式,所以末尾的1
可以是任何大于零的数字。基本上,您始终比较2个数字,在这种情况下,比较始终返回正数,因此它总是说将第二个数字移动到第一个数字前面 :)
这非常详细说明了:
https://dev59.com/Cmw15IYBdhLWcg3wfsBy - iulialsort()
改变数组本身(即就地排序),这正是原帖作者想要避免的。 - clint