underscore.js'deki _.each işlevinin nasıl kırılacağı


200

Underscore.js _.each()yönteminin yinelemelerini durdurmanın bir yolunu arıyorum , ancak çözümü bulamıyorum. jQuery .each()yaparsanız kırılabilir return false.

Her birini () alt çizgileri durdurmanın bir yolu var mı?

_([1,2,3]).each(function(v){
    if (v==2) return /*what?*/;
})

4
Bunun mümkün olduğunu düşünmüyorum, çünkü yerel forEachişlev de bu özelliği sunmuyor.
Felix Kling

8
Normalde eachbir kapakla kullanırken (çoğu dilde), önce listenizi filtrelemek istersiniz. Bu şekilde ondan kurtulmak için endişelenmenize gerek kalmaz. Genel olarak konuşursak, bir yinelemeden erken ayrılmanız gerekiyorsa, muhtemelen bunu yapmanın farklı bir yolu vardır.
Rob Hruska

İşte Groovy için, ilgili davranışın (bir kapanıştan kolayca kırılamaması ) JavaScript'e benzer olduğu birkaç soru each.
Rob Hruska

@Dmitry_F, diğerlerinin de belirttiği gibi, tam olarak sorduğunuz şeyi yapamazsınız. Ama gösterdiğim gibi, istediğiniz Array.everydavranışı taklit etmek için kullanabilirsiniz .
aeskr

@Rob. Şerefe. İlk yorum gerçekten yararlı. Gerçekten de bunu yapmanın farklı bir yolu vardı.
net.uk.sweet

Yanıtlar:


267

Dan kıramazsınız eachyöntem-it yerli emüle forEachyöntemin davranışını ve yerli forEach(istisna atan hariç) döngüden çıkabilmek için sağlamaz.

Ancak, tüm umutlar kaybolmaz! Array.everyYöntemi kullanabilirsiniz . :)

Bu bağlantıdan:

everycallbackdizide bulunan her öğe callbackiçin yanlış bir değer döndürülene kadar sağlanan işlevi bir kez yürütür . Böyle bir eleman bulunursa, everyyöntem hemen false değerini döndürür.

Başka bir deyişle, böyle kıvrımlı bir şey yapabilirsiniz ( JSFiddle bağlantısı ):

[1, 2, 3, 4].every(function(n) {
    alert(n);
    return n !== 3;
});

Bu uyaracaktır 1yoluyla 3ve sonra döngünün dışında "kırmak".

Bunu öğrenmek için memnun olacağım, böylece underscore.js kullandığınız gelmez bir sağlamak everyyöntemini-diyorlarsa every, ama bu bağlantı bahseder gibi, onlar da adlandırılan bir takma ad sağlamak all.


2
Underscore.js bunun için de bir uygulama sunuyor mu?
Felix Kling

1
@FelixKling, evet öyle. Bunu cevabıma ekledim.
aeskr

2
şu anda (05/2013), alt çizgilerdeki diziler için _.every()ne bir _.all()yöntem ne de bir yöntem vardır Array.every().
pkyeck

3
Bu işe yarayacak, ancak kullanmak için olağan bir neden every. Okunabilirliğe dikkat edin.
evanrmurphy

3
İçin alt çizgi dokümanlar _.each()özellikle döngüden çıkamayacağınız ve _.find()bunun yerine kullanmanızı öneriyor . http://underscorejs.org/#each
blatt

70

Güncelleme:

_.find öğesi bulunduğunda döngüden koptuğu için daha iyi olur:

var searchArr = [{id:1,text:"foo"},{id:2,text:"bar"}];
var count = 0;
var filteredEl = _.find(searchArr,function(arrEl){ 
              count = count +1;
              if(arrEl.id === 1 ){
                  return arrEl;
              }
            });

console.log(filteredEl);
//since we are searching the first element in the array, the count will be one
console.log(count);
//output: filteredEl : {id:1,text:"foo"} , count: 1

** Eski **

Koşullu olarak bir döngüden çıkmak istiyorsanız, _.each yerine _.filter api kullanın. İşte bir kod snippet'i

var searchArr = [{id:1,text:"foo"},{id:2,text:"bar"}];
var filteredEl = _.filter(searchArr,function(arrEl){ 
                  if(arrEl.id === 1 ){
                      return arrEl;
                  }
                });
console.log(filteredEl);
//output: {id:1,text:"foo"}

1
bu döngüyü bozmaz - sadece diziyi filtreler. dizide 2 değil 20.000 öğeniz olduğunu düşünün. giriş yaptığınız yalnızca yayınladığınız örneği verir, ancak döngü 20.000 kez çalışır :(
pkyeck

@pkyeck haklı olabilirsiniz, _find _ _filt'ten daha iyidir, elemnt bulunduktan sonra kırılır, işte keman: jsfiddle.net/niki4810/9K3EV
Nikhil

2
Bence bu cevap doğru cevap olmalı. _.findtam olarak sorulan şeyi yapar: geri arama geri dönene kadar liste üzerinde tekrarlayın true.
Fabien Quatravaux

Kabul edilen cevap (Array.every) nesneler üzerinde çalışmadığı için _.find () çalışacağı için bu yanıta oy verildi.
matt

Dokümanlarda önerilen budur: Her bir döngünün kırılamayacağını da not etmek iyidir - kırmak için _.find kullanın.
shaharsol

15

Bunun _.someyerine bir göz atabilirsiniz _.each. _.someyüklem doğru olduğunda listenin çapraz geçişini durdurur. Sonuç (lar) harici bir değişkende saklanabilir.

_.some([1, 2, 3], function(v) {
    if (v == 2) return true;
})

Bkz. Http://underscorejs.org/#some



3

Belki bir koşul karşılandığında işlenmeyi durduracak olan Underscore'un any () veya find () yöntemini istersiniz.



3

Bir bozamam forEachbunu ECMAscript 5 yerli davranışını taklit eder gibi alt çizgi içinde.


2

Dizinizin aslında boş bir nesne kullanarak dönebileceğiniz bir nesne olup olmadığına inanıyorum.

_.({1,2,3,4,5}).each(function(v){  
  if(v===3) return {}; 
});

Bu sadece EcmaScript v <5 ile gerçekleşir, çünkü alt nesnenin forEach'a sağlanan alternatifte boş nesneyi döndürüp döndürmediğinizi kontrol etmek için yaptığı karşılaştırma yalnızca yerel olan kullanılabilir olmadığında yapılır.
Alfonso de la Osa


1

Güncelleme:

Aslında içine bir hata atarak ve dışarıda yakalayarak "kırabilir": böyle bir şey:

try{
  _([1,2,3]).each(function(v){
    if (v==2) throw new Error('break');
  });
}catch(e){
  if(e.message === 'break'){
    //break successful
  }
}

Bunun, kodunuzun döngüde tetiklediği diğer istisnalarla ilgili bazı sonuçları vardır, bu yüzden dikkatli kullanın!


Bunun için çok aşağı oy almak nasıl seviyorum ve bu adam onun stackoverflow.com/a/2641374/674720
bm_i

1
Partiye geç kaldım ama adamın sadece önerdiğini söylemediğini, aynı zamanda iki alternatif daha (ve daha uygun) sunduğunu unutmayın. Sadece kullanıcı kesinlikle istemesi durumunda "hack" sundu. Bunun yerine sadece çirkin kesmek teklif ettin.
Areks

0

benim durumumda çalıştı

var arr2 = _.filter(arr, function(item){
    if ( item == 3 ) return item;
});
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.