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

sfl*_*che 157 javascript arrays

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

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

Aru*_*hny 323

你可以使用slice()制作副本然后反向()

var newarray = array.slice().reverse();
Run Code Online (Sandbox Code Playgroud)

var array = ['a', 'b', 'c', 'd', 'e'];
var newarray = array.slice().reverse();

console.log('a', array);
console.log('na', newarray);
Run Code Online (Sandbox Code Playgroud)

  • @OlegMatei 对整个数组进行切片仍然是切片。如果您了解 Array#slice 的作用,就不会感到困惑。扩展语法没有理由不那么令人困惑。 (9认同)
  • 我们能否花点时间来确定 JavaScript 还需要发展到什么程度?这就是我们最好的了吗?来吧 JavaScript!长大一点。 (6认同)
  • 我不建议使用这种方法,因为这是一种非常容易引起误解的做法。当您使用slice()而不实际切片时,这非常令人困惑。如果需要不变的反向,只需创建新的新副本即可:*** const newArray = [... array] .reverse()*** (5认同)
  • @Alex [slice](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)-如果省略了begin,则slice从索引0开始。与`array.slice(0)`相同 (2认同)
  • 我认为@Alex意味着"在你的答案中解释它"......无论如何......精彩的解决方案.谢谢! (2认同)

Bri*_*unt 85

在ES6中:

const newArray = [...array].reverse()
Run Code Online (Sandbox Code Playgroud)

  • 与接受的答案相比,它的表现如何?他们是一样的吗? (2认同)
  • 我一直在以更快的速度获取.slice。 (2认同)
  • @JamesCoyle可能取决于浏览器和操作系统,但是`slice`可能更快b / c`[...]`是可迭代的通用数组,因此不能做太多假设。同样,很长一段时间以来,`slice`可能得到了更好的b / c优化。 (2认同)
  • 有关复制数组的不同版本的基准,请参阅/sf/answers/3705087501/。 (2认同)

Rag*_*ghu 21

const originalArray = ['a', 'b', 'c', 'd', 'e', 'f'];

const newArray = Array.from(originalArray).reverse();

console.log(newArray);
Run Code Online (Sandbox Code Playgroud)


Pal*_*ine 11

ES2023 数组方法toReversed()

toReversed()方法以相反的顺序转置调用数组对象的元素并返回一个新数组。

const items = [1, 2, 3];
console.log(items); // [1, 2, 3]

const reversedItems = items.toReversed();
console.log(reversedItems); // [3, 2, 1]
console.log(items); // [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

浏览器兼容性

在此输入图像描述


Moh*_*man 7

ES6的另一个变体:

我们还可以.reduceRight()用于创建反向数组,而无需实际对其进行反转。

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

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

console.log(B);
Run Code Online (Sandbox Code Playgroud)

有用的资源:

  • `reduceRight` 很慢 af (3认同)
  • ((a,c)=> a.concat([c])`比((a,c)=>(a.push(c),a)更习惯。 (2认同)
  • @DragosRizescu 实际上看起来这是 3 个最佳答案中最快的一个。https://jsperf.com/reverse-vs-slice-reverse/3 (2认同)

小智 6

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

const foo = [1, 2, 3, 4];
const bar = foo.reduce((acc, b) => ([b, ...acc]), []);
Run Code Online (Sandbox Code Playgroud)

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

[]
[1] => [1]
[2, ...[1]] => [2, 1]
[3, ...[2, 1]] => [3, 2, 1]
[4, ...[3, 2, 1]] => [4, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

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

const baz = foo.reduceRight((acc, b) => ([...acc, b]), []);
Run Code Online (Sandbox Code Playgroud)


Aus*_*ton 6

尝试以下递归解决方案:

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!                              
Run Code Online (Sandbox Code Playgroud)

  • 这看起来会因空数组而中断。 (2认同)

she*_*dtu 5

有多种方法可以在不修改的情况下反转数组。其中两个是

var array = [1,2,3,4,5,6,7,8,9,10];

// Using Splice
var reverseArray1 = array.splice().reverse(); // Fastest

// Using spread operator
var reverseArray2 = [...array].reverse();

// Using for loop 
var reverseArray3 = []; 
for(var i = array.length-1; i>=0; i--) {
  reverseArray.push(array[i]);
}
Run Code Online (Sandbox Code Playgroud)

性能测试http://jsben.ch/guftu

  • 它应该是 `slice()` 而不是 `splice()`。后者返回一个空数组。 (2认同)