Soru JavaScript'te bir diziyi nasıl boşaltıyorum?


Bir dizi boşaltmak için bir yol var mı ve eğer varsa .remove()?

Örneğin,

A = [1,2,3,4];

Bunu nasıl boşaltabilirim?


2199
2017-08-05 09:08


Menşei


Burada farklı olasılıklara sahip bir kriter: jsben.ch/#/7QyI1 - EscapeNetscape


Cevaplar:


Mevcut bir diziyi temizlemenin yolları A:

Yöntem 1

(Bu soruya verdiğim orijinal cevaptı)

A = [];

Bu kod değişkeni ayarlayacaktır A yeni bir boş diziye. Eğer sahip değilseniz mükemmeldir orijinal diziye başvurular A başka bir yerde çünkü bu aslında yeni (boş) bir dizi yaratır. Bu diziye dikkat etmelisiniz çünkü bu diziyi başka bir değişken veya özellikten başvuruyorsanız, orijinal dizi değişmeden kalır. Yalnızca diziyi yalnızca orijinal değişkenine referans olarak kullanırsanız kullanın. A.

Bu aynı zamanda en hızlı çözümdür.

Bu kod örneği, bu yöntemi kullanırken karşılaşabileceğiniz sorunu gösterir:

var arr1 = ['a','b','c','d','e','f'];
var arr2 = arr1;  // Reference arr1 by another variable 
arr1 = [];
console.log(arr2); // Output ['a','b','c','d','e','f']

Yöntem 2 (gibi önerdi tarafından Matthew Crumley)

A.length = 0

Bu, mevcut diziyi, uzunluğunu 0 olarak ayarlayarak temizleyecektir. Bazıları, bunun, JavaScript'in tüm uygulamalarında işe yaramayacağını iddia etmişlerdir, ancak bunun böyle olmadığı ortaya çıkmaktadır. Ayrıca, ECMAScript 5'te "sıkı mod" kullanıldığında da çalışır; çünkü bir dizinin uzunluk özelliği bir okuma / yazma özelliğidir.

Yöntem 3 (gibi önerdi tarafından Anthony)

A.splice(0,A.length)

kullanma .splice() mükemmel çalışır, ama .splice() işlevi kaldırılan tüm öğelerle bir dizi döndürecek, aslında orijinal dizinin bir kopyasını döndürecektir. Karşılaştırmalar, bunun performans üzerinde hiçbir etkisi olmadığını göstermektedir.

Yöntem 4 (gibi önerdi tarafından tanguy_k)

while(A.length > 0) {
    A.pop();
}

Bu çözüm çok özlü değildir ve aynı zamanda, orijinal cevapta atıfta bulunulan önceki ölçütlerin aksine en yavaş çözümdür.

performans

Temizlemenin tüm yöntemleri mevcut diziYöntem 2 ve 3, performans açısından çok benzerdir ve yöntem 4'ten çok daha hızlıdır. Bkz. kıyaslama.

Tarafından işaret edildiği gibi Diadistis onların içinde Cevap Aşağıda, yukarıda açıklanan dört yöntemin performansını belirlemek için kullanılan orijinal kriterler kusurluydu. Orijinal kriter temizlenmiş diziyi yeniden kullandı, böylece ikinci yineleme zaten boş olan bir diziyi temizledi.

Aşağıdaki kriter bu kusuru giderir: http://jsben.ch/#/hyj65. Açıkça görülmektedir ki, yöntem # 2 (length özelliği) ve # 3 (ekleme) en hızlıdır (orijinal diziyi değiştirmeyen # 1 sayma yöntemi).


Bu sıcak bir konu ve çok tartışmanın sebebi oldu. Aslında birçok doğru cevap var ve bu cevap çok uzun bir süre için kabul edilen cevap olarak işaretlendiğinden, tüm yöntemleri burada içereceğim. Bu cevap için oy verirseniz, lütfen referans olarak verdiğim diğer cevapları da dikkate alın.


3457
2017-08-05 09:10



while (A.length) { A.pop(); }, ihtiyaç yok > 0 - Ivan Black
> 0 daha okunabilir IMHO. Ve ikisi arasında bir performans farkı yok. - Philippe Leybaert
@daghan, söylemeye çalıştığın her şey net değil. b sonra bile eski diziye bir referans tutar a yeni bir tane atandı. c ve d aynı diziye başvurmaya devam et. Çıkışlardaki fark bu nedenle bekleniyor. - shovavnik
@DiegoJancic Yöntem # 1 sayılmaz çünkü dizi temizlenmez. Yeni bir tane yaratıyor. Bir kıyaslamada yer almamalı. - Philippe Leybaert
Kullanamazsın while(A.pop()) dizideki bir öğenin falsey olması durumunda. Örneğin A = [2, 1, 0, -1, -2] A'ya eşittir [2, 1]. Üstelik while(A.pop() !== undefined) çalışmaz, çünkü değerlerden biri olarak tanımlanmamış bir dizi olabilir. Muhtemelen derleyicinin neden optimize etmediği. - Jonathan Gawrych


Orijinal dizisini saklamanız gerekiyorsa, diğer güncelleştirmeler de güncellenmiş olması gerekiyorsa, uzunluğunu sıfır olarak ayarlayarak yeni bir dizi oluşturmadan temizleyebilirsiniz:

A.length = 0;

2253
2017-08-05 16:29



@Acorn Evet, tüm tarayıcılarda çalışacaktır. - Matthew Crumley
ECMAScript 5 Standard bu konuda ne diyor? - Pacerier
@Pacerier: Hala ES5'te çalışıyor. Bölüm 15.4'ten: "... uzunluk özelliği değiştiğinde, değeri yeni uzunluktan daha küçük olmayan bir dizi dizini olan her özellik otomatik olarak silinir" - Matthew Crumley
@LosManos Katı modda bile, length özel bir özelliktir, ancak sadece okunmaz, bu yüzden hala çalışır. - Matthew Crumley
@MattewCrumley Bazı testler yaptım ve a.length = 0, dizinin tamamını etkin bir şekilde temizlemiyor gibi görünüyor. jsperf.com/length-equal-0-or-new-array Eğer bir referans noktanız varsa (ve saklamak istediğiniz fazladan özellikler eklemediyseniz), yeni bir dizi oluşturmak daha iyidir ve eskiden çöp toplayıcıya bırakır, bu da uygun olduğunda çalışır. - Paul Brewczynski


İşte en hızlı çalışan uygulama süre aynı diziyi tutmak ( "Değişken"):

Array.prototype.clear = function() {
  while (this.length) {
    this.pop();
  }
};

Bilginize Harita tanımlar clear() bu yüzden sahip olmak mantıklı görünebilir clear() için Dizi çok.

Ya da Underscore.js karışımı:

_.mixin({
  clearArray: function(array) {
    while (array.length) {
      array.pop();
    }
  }
});

Ya da basit bir işlev:

function clearArray(array) {
  while (array.length) {
    array.pop();
  }
}

daktilo ile yazılmış yazı versiyon:

function clearArray<T>(array: T[]) {
  while (array.length) {
    array.pop();
  }
}

FYI basitleştirilemez while (array.pop()): Testler başarısız olur.

Ve onunla yapılan testler:

describe('Array', () => {
  it('should clear the array', () => {
    let array = [1, 2, 3, 4, 5];
    array.clear();
    expect(array.length).toEqual(0);
    expect(array[0]).toEqual(undefined);
    expect(array[4]).toEqual(undefined);

    // Even with undefined or null inside
    array = [1, undefined, 3, null, 5];
    array.clear();
    expect(array.length).toEqual(0);
    expect(array[0]).toEqual(undefined);
    expect(array[4]).toEqual(undefined);
  });
});

Burada güncellenen jsPerf: http://jsperf.com/array-destroy/32  http://jsperf.com/array-destroy/152


256
2018-06-25 20:32



TT cevabınız, doğru ve hızlı (aynı zamanda) ancak biraz daha az "upvotes" olan tekdir. Eh, insanlar oldukça yavaş ve güzel çözümler gibi görünüyor: / - Ai_boy
@naomik Ama bu varsayılan olarak orada olması gereken temel işlevselliklerden biridir. - thefourtheye
@thefourtheye Performans için iyi bir çözüm, ben @naomik ile aynı fikirde olsam da, yerli nesneleri değiştirmemelisiniz. Orada olması gerektiğini söyleyen nokta, problemi değiştiriyorsun globaller, hangi kötü. Kodunuzu başkalarının kullanması için öngörüyorsanız, öngörülemeyen yan etkileri olmamalıdır. Başka bir kütüphane var mı düşünün Ayrıca değiştirildi Array.prototype ve biraz farklı bir şey yapıyordu, sonra tüm kod boyunca [].clear() biraz yanıldı. Bu hata ayıklamak için eğlenceli olmaz. Yani genel mesaj şudur: Küreselleri modifiye etmeyin. - jpillora
@thefourtheye Küresel kapsamı değiştirmemek için tüm nokta çünkü bilmeyeceksin Bir başkasının kodu zaten ismiyle (veya olacaksa). Yerel kapsam içinde bir işlev öneririm. Yani, uygulamanızın / kütüphanenin içinde Hayatta, yap function clear(arr) { while(arr.length) arr.pop(); }sonra dizileri temizle clear(arr) yerine arr.clear(). - jpillora
Bu yöntemin çok daha yavaş olduğu ortaya çıkıyor. .splice() ve .length=0. Ölçütler doğru değildi. Güncellenmiş cevabımı görün. - Philippe Leybaert


Daha çapraz tarayıcı dostu ve daha uygun bir çözüm kullanmak olacaktır splice A dizisinin içeriğini aşağıdaki gibi boşaltmak için yöntem:

A.splice(0, A.length);


182
2017-11-15 09:49



Bu neden daha çok tarayıcı dostu olur? Hangi tarayıcıların A.length ile ilgili sorunları var? - stricjux
@ jm2 söyledikleriniz tam olarak doğru değil. Aslında söz konusu diziyi değiştirir ve daha sonra tüm referanslar etkilenir. JsFiddle'ımdaki sınava bak: jsfiddle.net/shamasis/dG4PH - Shamasis Bhattacharya
@alex hayır, değil splice diziyi değiştirir ve silinmiş girdileri döndürür. Önce dokümanları oku: developer.mozilla.org/en-US/docs/JavaScript/Reference/... - David
Elde edilen diziyi kullanarak iade edilmesini engelleyebiliriz. virgül operatörü: A.splice(0, A.length),0;. Bu geri dönüş değeri 0 tıpkı A.length = 0; olur. Ortaya çıkan dizi hala oluşturulur ve meli komut dosyasının daha yavaş çalışmasına neden olur:jsperf ~% 56 daha yavaş). Neden olmasa da tarayıcı uygulaması bunu etkileyecektir. splice ayardan daha hızlı olurdu length. - Evan Kennedy
Ayrıca şunu da buldum A.splice(0) ayrıca çalışır. - corwin.amber


Şu ana kadar 2739 imvizyona sahip olmayan cevaplar yanıltıcı ve yanlıştır.

Soru şu: "Mevcut dizinizi nasıl boşaltabilirsiniz?" Örneğin. için A = [1,2,3,4].

  1. "DiyerekA = [] cevap "cahil ve kesinlikle yanlıştır. [] == [] olduğu yanlış.

    Bunun nedeni, bu iki dizinin, kendi iki kimliğiyle, dijital dünyada kendi alanlarını kendi başına alan iki ayrı, bireysel nesnesi olmasıdır.


Diyelim ki anneniz çöp tenekesini boşaltmanızı ister.

  • İstediğin şeyi yapmış gibi yeni bir tane getiremezsin.
  • Bunun yerine çöp kutusunu boşaltabilirsiniz.
  • Doldurulmuş olanı yeni bir boş kutuyla değiştirmezsiniz ve doldurulmuş kutudan "A" etiketini almazsınız ve A = [1,2,3,4]; A = [];

Bir dizi nesnesini boşaltmak şu ana kadar en kolay şey:

A.length = 0;

Bu şekilde, "A" altındaki kutu sadece boş değil, aynı zamanda yeni kadar temiz!


  1. Ayrıca, kutu boş olana kadar çöpü elden çıkarmanız gerekmez! Boş olana kadar çöpü almamak için, mevcut olanı, bir turda tamamen boşaltmanız istendi:

    while(A.length > 0) {
        A.pop();
    }
    
  2. Ayrıca, sol elinizi çöp kutusunun altına koymak için, içeriğinizi aşağıdaki gibi çekebilmek için sağ üst tarafınızla tutarak:

    A.splice(0, A.length);
    

Hayır, onu boşaltmanız istendi:

A.length = 0;

Bu, belirli bir JavaScript dizisinin içeriğini doğru şekilde boşaltan tek koddur.


61
2018-04-30 15:18



Önerilen çözümünüzle ilgili tek sorun, çöp kutusunun hala var olması, aynı zamanda çöp panosunun olmadığını belirten ilan panosunu değiştirmenizdir. Eski diziye bir referans hala mevcut olmalıdır. Çöp toplayıcısını .length = 0 olarak ayarlarken, diziye ve özelliklerine yapılan tüm referansları da sileceğinden emin olabilir misiniz? Sanırım öyle değil ama bana göre bu sihir. En az söylemek için karışıklıktan kaçınmak için bir .clear () yöntemi tercih edilir. - momo
Bu çözümün yanlış olduğunu asla söylemedim. Sorun şu ki bu iş parçacığı tamamen gereksizdir. 3000'den fazla oy, EMCA çatlak baş geliştiricileri için böyle bir yöntem eklemenin en iyi yolun ne kadar geçerli bir durum olduğunu anlamaya çalışıldığını gösteriyor. Bunu anlamak için kimse gitmemeli. Bunu yapmanın üç dört yolu vardır. Bazı ölçütlerde uzunluk çözümleri diğerlerinden çok daha yavaştır. Ayrıca, herhangi bir makul geliştirici için .length = 0 değerini ayarlama fikri tatmin edici değildir. - momo
Çünkü yapması gereken şeyleri başarmak için tüm referanslar kaldırılmalıdır. .length = 0 bir yöntem çağrısı bile değil, bu nedenle 0'a ayarlandığında başka eylemler gerçekleştirilirse (bu, çoğu tarayıcıda tanımlayıcı aracılığıyla). yapmak. - momo
Bu nedenle, kendimi temizlemeyi tercih ederim. Net bir yöntem prototip olabilir ama bu sadece çirkin. Benim düşüncem şu ki, bu uygulama zaten mevcut olmalıydı, böylece 10 000'den fazla geliştiricinin daha fazla zaman ölçmek için harcayan tüm diğer kişileri göz önünde bulundurmadan sadece bu iş parçasını okuması gerekmiyordu. - momo
dizininizi boşaltmanın yeni bir veriyi doldurması için tek bir yol var ve onu tekrar atın. Diğerleri ya, ya da gülünç verimsiz ve affedilmez cpu aç. Tek pratik alternatif A(n) = A.splice( 0, A.length );önceki içeriğinizi yedeklemeniz gerekiyorsa. Not; Array.length Bu temel gerçeği kaçırmış olmanız durumunda okuma-yazma özelliği \ yöntemidir. Anlamı, onu yeni bir boyuta genişletebilir, istediğiniz uzunlukta uzunluğunu kesemezsiniz ve diğerlerinin yanı sıra tüm üyelerin uzunluğunu 0'a kısaltabilirsiniz. Bu dizinin bir İsviçre bıçağıdır. - Bekim Bacaj


Performans testi:

http://jsperf.com/array-clear-methods/3

a = []; // 37% slower
a.length = 0; // 89% slower
a.splice(0, a.length)  // 97% slower
while (a.length > 0) {
    a.pop();
} // Fastest

59
2018-05-14 07:14



Yüzde değişikliklerini eklemek, platformunuzu da kaydetmeden çok kullanışlıdır. Makinemde pop, Chrome 34'te yalnızca çok hafif derecede hızlıdır, ancak en son Firefox'ta [] 'den daha yavaştır. - Matt Styles
Firefox'taki Test 39.0 32-bit Windows NT 6.3 üzerinde 64-bit, a = [] en hızlı! - Reza-S4
Bu test sonucu, Chrome altında kesinlikle balık gibi bir şey var. Nasıl oluyor da popping döngüsü diğer 3 çözümden o kadar hızlı olabilir? - chqrlie
@chqrlie değil. Bu en yavaş yöntem. Kıyaslama testi hatalı. - Philippe Leybaert
Lütfen bu cevabı yanlış olduğundan ve anlamsız bir kusurlu teste sahte delil olarak bağlantı vermekten çekinmeyin. - James Wakefield


Dizilerinizin "temizlendiğinden" emin olmak için bunu JavaScript dosyanıza ekleyebilirsiniz:

Array.prototype.clear = function() {
    this.splice(0, this.length);
};

Sonra böyle kullanabilirsiniz:

var list = [1, 2, 3];
list.clear();

Ya da bir şeyi yok etmediğinden emin olmak istiyorsan:

if (!Array.prototype.clear) {
    Array.prototype.clear = function() {
       this.splice(0, this.length);
    };
}

Pek çok insan, yerel nesneleri (Array gibi) değiştirmemelisiniz ve aynı fikirde olma eğilimindeyim. Lütfen bunun nasıl ele alınacağına karar verirken dikkatli olun.


32
2017-12-11 02:58



@naomik Sebebinizi açıklayabiliyor musunuz, böyle bir şeyi neden yapmıyorsunuz? - Undefined
Array ve String gibi javascript ilkel işlevlerini değiştirmek için "üzerine kaşıdı". Zaten mevcut bir işlevi aşırı yükleyebilir ve nesne sınıfını çöpe atabilirsiniz. Zaten net olan () ve farklı bir şekilde davranmasını bekler bir karanlık javascript motoru olabilir. Dikkatlice basmak tek söylediklerim. - Design by Adrian
Bir dizinin üyeleri üzerinde bir foreach yapmanın aniden bir clear anahtar? - ErikE
Bir referans olarak: Niçin yerli nesneleri yaygınlaştırmak kötü bir uygulamadır? - Emile Bergeron


Array.prototype.clear = function() {
    this.length = 0;
};

Ve ara: array.clear();


16
2018-02-22 21:28



Lütfen yerel nesnelerin değiştirilmesini teşvik etmeyin. - user633183
insanlar neden kabul edilen cevabı alma ve prototip işlevine sokma eğilimine sahipler? Bunu projelerinizde mi yapıyorsunuz? Her projeye dahil edeceğiniz büyük bir prototip eklemeler kütüphaneniz var mı? - nurettin
Neden sadece array.length = 0 yazmıyorsunuz? - Design by Adrian
@naomik "Lütfen yerel nesnelerin değiştirilmesini teşvik etmeyin." - Buna tamamen katılıyorum, ama cümlenin tek başına tekrarlanması kibirli olarak karşımıza çıkıyor. Böyle bir çözüm öneren birinin, muhtemelen sonuçlardan haberdar olmaması ve kısa bir açıklama ya da bir link vermek yerine bu çizgiyi bırakması, başka bir anlam taşımamaktadır. "biz, sizden daha akıllı insanlar, bunu yapmamanızı söyleyelim, çünkü daha iyi biliyoruz". - John Weisz
Bir referans olarak: Niçin yerli nesneleri yaygınlaştırmak kötü bir uygulamadır? - Emile Bergeron


Hem cevaplarda hem de yorumlarda pop / shift performansı ile ilgili bir sürü karışıklık ve yanlış bilgilendirme var. While / pop çözümü (beklendiği gibi) en kötü performans. Gerçekte olan şey, kurulumun snippet'i bir döngüde çalıştıran her örnek için yalnızca bir kez çalıştırılmasıdır. Örneğin:

var arr = [];

for (var i = 0; i < 100; i++) { 
    arr.push(Math.random()); 
}

for (var j = 0; j < 1000; j++) {
    while (arr.length > 0) {
        arr.pop(); // this executes 100 times, not 100000
    }
}

Doğru çalışan yeni bir test oluşturdum:

http://jsperf.com/empty-javascript-array-redux

Uyarı: Testin bu sürümünde bile gerçek farkı göremezsiniz çünkü dizinin klonlanması test süresinin çoğunu alır. Hala gösteriyor ki splice diziyi temizlemek için en hızlı yoldur [] göz önünde bulundurulduğu için en hızlı olanı ise aslında mevcut diziyi temizlememektedir.


15
2018-02-16 18:52



Çok iyi bir nokta! Orijinal cevabı doğru değerlendirme sonuçlarıyla güncelleyeceğim. - Philippe Leybaert
Kimsenin o referans noktasını görmediğine inanamıyorum. Yarım milyondan fazla görüntüleme ile birisinin bunu fark etmesini beklersiniz. Büyük iş Diadistis - Philippe Leybaert