在 Javascript 中反转数组而不改变原始数组

IT技术 javascript arrays
2021-01-25 09:47:16

Array.prototype.reverse 原地反转数组的内容(带有突变)...

是否有类似的简单策略来反转数组而不改变原始数组的内容(没有突变)?

6个回答

您可以使用片() 使该拷贝逆转()

var newarray = array.slice().reverse();

@Alex slice - If begin is omitted, slice begins from index 0.- 所以它与array.slice(0)
2021-03-14 09:47:16
我认为@Alex 的意思是“在你的答案中解释它”......无论如何......出色的解决方案。谢谢!
2021-03-19 09:47:16
我们能不能花点时间确定 JavaScript 需要进一步发展多少?这是我们得到的最好的吗?通用 JavaScript!长大一点。
2021-03-27 09:47:16
@OlegMatei 切片整个阵列仍在切片。如果您了解它的作用,就不会感到困惑Array#slice没有理由传播语法应该不那么令人困惑。
2021-03-30 09:47:16
我不建议使用这种方法,因为这是非常具有误导性的做法。当您使用 slice() 并且实际上没有切片时,这非常令人困惑。如果您需要不可变的反向,只需创建新的副本: const newArray = [...array].reverse()
2021-04-07 09:47:16

在 ES6 中:

const newArray = [...array].reverse()
@JamesCoyle 这可能取决于浏览器和操作系统,但slice可能会更快 b/c[...]是通用的可迭代到数组,因此无法做出尽可能多的假设。同样,这可能slice是更好的优化 b/c 它已经存在很长时间了。
2021-03-13 09:47:16
请参阅stackoverflow.com/a/52929821/1480587,了解用于复制阵列的不同版本的基准测试。
2021-03-26 09:47:16
我一直在变得.slice更快。
2021-03-27 09:47:16
我的想法正是如此。
2021-04-02 09:47:16
与接受的答案相比,它的表现如何?他们是一样的吗?
2021-04-11 09:47:16

另一个 ES6 变体:

我们还可以使用.reduceRight()来创建一个反转数组,而无需实际反转它。

let A = ['a', 'b', 'c', 'd', 'e', 'f'];

let B = A.reduceRight((a, c) => (a.push(c), a), []);

console.log(B);

有用的资源:

@DragosRizescu 实际上看起来这是 3 个最佳答案中最快的。jsperf.com/reverse-vs-slice-reverse/3
2021-03-13 09:47:16
(a, c) => a.concat([c]) 感觉比 (a, c) => (a.push(c), a)
2021-03-20 09:47:16
reduceRight 很慢
2021-03-22 09:47:16
@DragosRizescu 你能分享一些样本测试结果吗?
2021-04-04 09:47:16
这是一个你可以玩的仓库:(不是最好的例子,但不久前在 React 上下文中与某人有过这个争论,因此我把它放在一起):github.com/rizedr/reduce-vs-reduceRight
2021-04-11 09:47:16

试试这个递归解决方案:

const reverse = ([head, ...tail]) => 
    tail.length === 0
        ? [head]                       // Base case -- cannot reverse a single element.
        : [...reverse(tail), head]     // Recursive case

reverse([1]);               // [1]
reverse([1,2,3]);           // [3,2,1]
reverse('hello').join('');  // 'olleh' -- Strings too!                              
这看起来会因空数组而中断。
2021-03-31 09:47:16

ES6 的替代使用.reduce()和传播。

const foo = [1, 2, 3, 4];
const bar = foo.reduce((acc, b) => ([b, ...acc]), []);

基本上它所做的是创建一个新数组,其中包含 foo 中的下一个元素,并在 b 之后为每次迭代扩展累积数组。

[]
[1] => [1]
[2, ...[1]] => [2, 1]
[3, ...[2, 1]] => [3, 2, 1]
[4, ...[3, 2, 1]] => [4, 3, 2, 1]

或者.reduceRight()如上所述这里,但没有.push()突变。

const baz = foo.reduceRight((acc, b) => ([...acc, b]), []);