web-dev-qa-db-ja.com

underscore.jsの_.each関数を壊す方法

Underscore.js _.each()メソッドの反復を停止する方法を探していますが、解決策が見つかりません。 return falseを実行すると、jQuery .each()が破損する可能性があります。

アンダースコアeach()を停止する方法はありますか?

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

eachメソッドから中断することはできません。ネイティブforEachメソッドの動作をエミュレートし、ネイティブforEachはループをエスケープする機能を提供しません(例外をスローする以外)。

ただし、すべての希望が失われるわけではありません!Array.every メソッドを使用できます。 :)

そのリンクから:

everyは、callbackがfalse値を返す要素が見つかるまで、配列に存在する各要素に対して、提供されたcallback関数を1回実行します。そのような要素が見つかった場合、everyメソッドはすぐにfalseを返します。

つまり、次のように複雑なことができます( JSFiddleへのリンク ):

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

これは、1を介して3に警告し、ループから抜け出します。

Underscore.jsを使用しているため、doeseveryメソッドを提供していることを知って喜んでいるでしょう- every ですが、そのリンクが言及している、彼らはまたallと呼ばれるエイリアスを提供します。

264
aeskr

更新:

_.findは、要素が見つかったときにループを抜けるのでより良いでしょう:

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

**古い**

条件付きでループを抜けたい場合は、_。eachの代わりに_.filter apiを使用します。これがコードスニペットです

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"}
69
Nikhil

_.someの代わりに__.eachを見ることができます。 _.someは、述語が真になると、リストの走査を停止します。結果は外部変数に保存できます。

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

http://underscorejs.org/#some を参照してください

15
Joan
_([1,2,3]).find(function(v){
    return v if (v==2);
})
6
Rockyboy_ruby

アンダースコアのany()またはfind()が必要な場合があります。これらは、条件が満たされたときに処理を停止します。

3
grantwparks

EcmaScript 5のネイティブな動作をエミュレートするため、アンダースコアでforEachを壊すことはできません。

3
JaredMcAteer

他の答えと同様に、それは不可能です。アンダースコアのブレーカーに関するコメントです アンダースコアの問題#21

3
czizzy

また、各ループを分割することはできないことに注意してください。分割するには、代わりに_.findを使用します。

http://underscorejs.org/#each

2
percebus

あなたの配列が実際には空のオブジェクトを使用して返すことができるオブジェクトだったと信じています。

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

更新:

内部でエラーをスローし、外部でそれをキャッチすることで、実際に「ブレーク」できます。次のようなものです。

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

これは明らかに、コードがループ内でトリガーする他の例外に関していくつかの意味があるので、注意して使用してください!

1
bm_i

私の場合は働いた

var arr2 = _.filter(arr, function(item){
    if ( item == 3 ) return item;
});
0
aleXela