Orijinal diziyi değiştirmeden Javascript'te diziyi ters çevir


190

Array.prototype.reverse yerinde bir dizinin içeriğini tersine çevirir (mutasyon ile) ...

Orijinal dizinin içeriğini değiştirmeden (mutasyon olmadan) bir diziyi tersine çevirmek için benzer basit bir strateji var mı?



Farklı seçenekleri karşılaştıran bir kıyaslama: jsben.ch/HZ7Zp
Solomon Ucko

Yanıtlar:


378

Sen kullanabilirsiniz dilim () bir kopyası daha sonra yapmak ) (ters it

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


Lütfen herhangi bir parametre olmadan dilim () 'i açıklar mısınız?
Alex

3
@Alex slice - If begin is omitted, slice begins from index 0.- yani aynıarray.slice(0)
Arun P Johny

2
Sanırım @Alex 'cevabında açıkla' demek istedi ... ne olursa olsun ... Mükemmel çözüm. Teşekkürler!
sfletche

15
Bu yaklaşımı kullanmanızı tavsiye ETMEM çünkü çok yanıltıcı bir uygulamadır. Dilim () kullandığınızda ve aslında hiçbir şey dilimlemediğinizde çok kafa karıştırıcıdır. Değişmez tersine ihtiyacınız varsa, sadece yeni bir kopya oluşturun: const newArray = [... dizi] .reverse ()
Oleg Matei

106

ES6'da:

const newArray = [...array].reverse()

2
Bunun performansı, kabul edilen cevabın performansı ile nasıl karşılaştırılır? Bunlar aynı mı?
Katie

@Katie Çok basit, ikisi de çok hızlı, Chrome [...].reverseçok basit bir test durumunda bir avantaj sağlıyor. jsperf.com/reverse-vs-slice-reverse/1
Brian M. Hunt

4
Sürekli .sliceolarak çok daha hızlı hale geliyorum .
James Coyle

3
@JamesCoyle Muhtemelen tarayıcıya ve işletim sistemine bağımlıdır, ancak slicedaha hızlı olması muhtemeldir b / c [...]diziye yinelenebilir bir jeneriktir, bu nedenle çok fazla varsayım yapamaz. Ayrıca, muhtemelen slicedaha iyi optimize edilmiş b / c uzun süredir var.
Brian M. Hunt

Benim düşüncelerim tam.
James Coyle

11

Başka bir ES6 varyantı:

Ayrıca .reduceRight()tersine çevirmeden tersine çevrilmiş bir dizi oluşturmak için de kullanabiliriz .

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

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

console.log(B);

Yararlı Kaynaklar:


2
reduceRightyavaş
Dragos Rizescu

@DragosRizescu Bazı örnek test sonuçlarını paylaşabilir misiniz?
Mohammad Usman

1
İşte oynayabileceğiniz bir repo: (en iyi örnek değil, ancak bir süre önce React bağlamında biriyle bu argümanı vardı, bu yüzden bir araya getirdim): github.com/rizedr/reduce-vs-reduceRight
Dragos Rizescu

4
(a, c) => a.concat([c])daha deyimsel hissediyor(a, c) => (a.push(c), a)
Kyle Lin

1
@DragosRizescu aslında en iyi 3 cevabın en hızlısı gibi görünüyor. jsperf.com/reverse-vs-slice-reverse/3
DBosley

7

Bu özyinelemeli çözümü deneyin:

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!                              

1
Boş diziler için kırılacak gibi görünüyor.
Matthias

6

Kullanmak .reduce()ve yaymak için bir ES6 alternatifi .

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

Temel olarak yaptığı şey, foo'daki sonraki öğeyle yeni bir dizi oluşturmak ve b'den sonra her yineleme için biriken diziyi yaymaktır.

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

Alternatif .reduceRight()olarak burada yukarıda belirtildiği gibi, ancak .push()mutasyon olmadan .

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

4

Bir diziyi değiştirmeden tersine çevirmenin birden çok yolu vardır. İkisi

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]);
}

Performans testi http://jsben.ch/guftu


0

INTO düz Javascript:

function reverseArray(arr, num) {
  var newArray = [];
  for (let i = num; i <= arr.length - 1; i++) {
    newArray.push(arr[i]);
  }

  return newArray;
}

0

Yalnızca gösterim amacıyla değişken takas ile yerinde tersine çevirme (ancak değiştirmek istemiyorsanız bir kopyasına ihtiyacınız vardır)

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]] 
}

-4

ES6:

const reverseArr = [1,2,3,4].sort(()=>1)

4
SO hoş geldiniz, Radion! Bir cevaptan ayrılırken, yanıtınızın neden işe yaradığını ve bu sonuca neden geldiğinizi açıklamak genellikle iyi bir fikirdir, bu yeni kullanıcıların belirttiğiniz etkileşimleri ve dilleri anlamalarına yardımcı olur.
Ethan Field

Radion'un savunmasında: P 1, sonunda sıfırdan büyük bir şey olabilirdi, çünkü Array.prototype.sortgeri arama (ya da böyle denir compare function) böyle çalışır. Temelde her zaman 2 sayıyı karşılaştırırsınız ve bu durumda karşılaştırma her zaman pozitif olur, bu yüzden her zaman
birincinin

8
sort()OP'yi kaçınmak istediği diziyi değiştirir (yani, yerinde sıralar).
Clint Harris

5
Bu cevap çeşitli şekillerde yanlıştır. (1) @ClintHarris'in işaret ettiği gibi diziyi değiştirir, bu nedenle .reverse () öğesinden daha iyi değildir. (2) karşılaştırıcınız yasa dışıdır; a, b için 1 döndürdüğünüzde, b, a için negatif bir sayı döndürmeniz gerekir. Cevabınız diziyi bazı uygulamalarda tersine çevirirse, tamamen şans eseri.
Don Hatch
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.