web-dev-qa-db-fra.com

comment casser la fonction _.each dans underscore.js

Je cherche un moyen d'arrêter les itérations de la méthode underscore.js _.each(), mais je ne trouve pas la solution. jQuery .each() peut s'arrêter si vous faites return false.

Existe-t-il un moyen d’arrêter de souligner chacun ()?

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

Vous ne pouvez pas rompre avec la méthode each; elle émule le comportement de la méthode native forEach et la méthode native forEach ne permet pas d'échapper à la boucle (à l'exception du lancement d'une exception).

Cependant, tout espoir n'est pas perdu! Vous pouvez utiliser la méthode Array.every . :)

De ce lien:

every exécute la fonction callback fournie une fois pour chaque élément présent dans le tableau jusqu'à ce qu'il en trouve un où callback renvoie une valeur false. Si un tel élément est trouvé, la méthode every renvoie immédiatement la valeur false.

En d’autres termes, vous pourriez faire quelque chose de compliqué comme ceci ( lien vers JSFiddle ):

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

Cela alertera de _1_ à _3_, puis "se séparera" de la boucle.

Vous utilisez underscore.js. Vous serez donc ravi d'apprendre qu'il fournit une méthode every; ils l'appellent every , mais comme ce lien mentionne, ils fournissent également un alias appelé all.

266
aeskr

Mise à jour:

_.find serait mieux car il sort de la boucle quand l'élément est trouvé:

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

** Vieux **

Si vous souhaitez interrompre conditionnellement une boucle, utilisez _.filter api au lieu de _.each. Voici un extrait de code

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

Vous pouvez jeter un oeil à _.some au lieu de _.each. _.some arrête de parcourir la liste une fois qu'un prédicat est vrai. Les résultats peuvent être stockés dans une variable externe.

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

Voir http://underscorejs.org/#some

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

Peut-être voulez-vous que Underscore soit any () ou find (), qui arrêtera le traitement dès qu'une condition sera remplie.

3
grantwparks

Vous ne pouvez pas séparer un forEach d'un trait de soulignement, car il émule le comportement natif d'EcmaScript 5.

3
JaredMcAteer

Comme les autres réponses, c'est impossible. Voici le commentaire sur le séparateur dans le trait de soulignement numéro de soulignement # 21

3
czizzy

Il est également bon de noter que chaque boucle ne peut pas être séparée de - pour rompre, utilisez plutôt _.find.

http://underscorejs.org/#each

2
percebus

Je crois que si votre tableau était en réalité un objet, vous pouvez le retourner en utilisant un objet vide.

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

Mise à jour:

Vous pouvez réellement "casser" en jetant une erreur à l'intérieur et en la rattrapant à l'extérieur: quelque chose comme ceci:

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

Cela a évidemment des implications sur toute autre exception déclenchée par votre code, utilisez donc avec prudence!

1
bm_i

travaillé dans mon cas

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