Orijinal diziyi değiştirmeden bir diziyi nasıl sıralayabilirsiniz?


231

Girilen dizinin sıralanmış bir kopyasını döndüren bir sıralama işlevi istediğimi varsayalım. Safça denedim

function sort(arr) {
  return arr.sort();
}

ve bunu test ettim, bu da benim sortyöntemimin diziyi değiştirdiğini gösteriyor

var a = [2,3,7,5,3,7,1,3,4];
sort(a);
alert(a);  //alerts "1,2,3,3,3,4,5,7,7"

Ben de bu yaklaşımı denedim

function sort(arr) {
  return Array.prototype.sort(arr);
}

ama hiç işe yaramıyor.

Bunun etrafında basit bir yol var mı, tercihen kendi sıralama algoritmamı elle yuvarlamayı veya dizinin her öğesini yenisine kopyalamayı gerektirmeyen bir yol var mı?


1
dizinin derin bir kopyasını oluşturun ve diziyi sıralayın.
evanmcdonnal

1
@evanmcdonnal İstenilen her şey dizideki her öğenin tekrarı değil, yeniden sıralanıyorsa, sığ bir kopya yeterince iyi olabilir.
Kekoa

.sortthisdeğerin dizi olmasını gerektirir , bu nedenle son snippet'in çalışması için bunu yaparsınız .sort.call(arr)(sorununuzu çözmese de).
pimvdb

@Kekoa Evet, bu iyi bir nokta. Sadece öğelerin sırasını değiştirirseniz, öğelerin kendilerini değil, daha fazla bellek tüketmeye gerek yoktur.
evanmcdonnal

zzzzBov'un yöntemi bir cazibe gibi çalışıyor! stackoverflow.com/a/9592774/7011860
Samet M.

Yanıtlar:


224

Diziyi kopyalamanız yeterlidir. Bunu yapmanın birçok yolu vardır:

function sort(arr) {
  return arr.concat().sort();
}

// Or:
return Array.prototype.slice.call(arr).sort(); // For array-like objects

2
Bu derin bir kopya mı yapacak, yani iç içe geçmiş nesneler ve diziler de kopyalanacak mı?
Peter Olson

2
Söylemenin concatüzerinde kullanmanın herhangi bir avantajı var mı yoksa slice(0)hepsi hemen hemen aynı mı?
JaredPar

3
@PeterOlson Hayır, sığ bir kopya. Gerçekten derin bir kopya istiyorsanız, mevcut mükemmel yanıtları bulmak için Yığın Taşması'ndaki arama özelliğini kullanın.
Rob W

11
Dilim şimdi çok daha hızlı olarak bildirildi
Zander Brown

3
neden Array.prototype.slice.call(arr).sort();yerine arr.slice().sort();?
Olivier Boissé


61

Takip etmeyi dene

function sortCopy(arr) { 
  return arr.slice(0).sort();
}

slice(0)İfadesi elemanı 0 dizi başlayan bir kopyasını oluşturur.


32

Bir diziyi kopyalamak için bağımsız değişkeni olmayan dilimi kullanabilirsiniz:

var foo,
    bar;
foo = [3,1,2];
bar = foo.slice().sort();

Bu cevap harika! JavaScript bu dereceye kadar mutasyon izin şaşırdım. Yanlış görünüyor. Tekrar teşekkürler.

12

Bunu da yapabilirsiniz

d = [20, 30, 10]
e = Array.from(d)
e.sort()

Bu şekilde d mutasyona uğramaz.

function sorted(arr) {
  temp = Array.from(arr)
  return temp.sort()
}

//Use it like this
x = [20, 10, 100]
console.log(sorted(x))

Bu cevap güzel
Leasye

1

Derin bir kopya yapmak isteyen herkes (örneğin diziniz nesne içeriyorsa) şunları kullanabilir:

let arrCopy = JSON.parse(JSON.stringify(arr))

Sonra arrCopydeğiştirmeden sıralama yapabilirsiniz arr.

arrCopy.sort((obj1, obj2) => obj1.id > obj2.id)

Lütfen dikkat: bu çok büyük diziler için yavaş olabilir.


Bu, ikinci örneğiniz -yerine yerine çalışacaktır >.
pootzko

0

Kopyalarımın çoğu için Object.assign () kullanıyorum :

var copyArray = Object.assign([], originalArray).sort();

Ancak, OP yorumları inceledikten sonra, biraz derin kopyalama araştırdım ve Object.assign sadece sığ bir kopya gerçekleştirmekle kalmaz, aynı zamanda sadece numaralandırılabilir ve kendi özelliklerini de seçer ( bu yazıda yanıtlandığı gibi ).

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.