Circuit Court-Circuit.pourchasse comme appeler break

[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

Comment puis-je faire cela en utilisant la nouvelle méthode forEach en JavaScript? J'ai essayé return; , return false; et break . break se bloque et return ne fait rien, mais continuer itération.

1061
demandé sur Alexander Abakumov 2010-04-15 01:57:31
la source

28 ответов

il n'y a pas de capacité intégrée à break dans forEach . Pour interrompre l'exécution, il faudrait faire une exception. par exemple.

var BreakException = {};

try {
  [1, 2, 3].forEach(function(el) {
    console.log(el);
    if (el === 2) throw BreakException;
  });
} catch (e) {
  if (e !== BreakException) throw e;
}

les exceptions JavaScript ne sont pas très jolies. Une boucle traditionnelle for pourrait être plus appropriée si vous avez vraiment besoin de break à l'intérieur.

Utilisation Array#some

à la place, utilisation Array#some :

[1, 2, 3].some(function(el) {
  console.log(el);
  return el === 2;
});

cela fonctionne parce que some renvoie true dès que l'un des callbacks, exécuté dans l'ordre de la matrice, renvoie true , court-circuitant l'exécution du reste.

some , son inverse every (qui s'arrêtera sur un return false ), et forEach sont tous ECMAScript cinquième édition les méthodes qui devront être ajoutées au Array.prototype sur les navigateurs où elles sont manquantes.

1488
répondu bobince 2016-09-10 00:01:04
la source

il y a maintenant une façon encore meilleure de le faire dans ECMAScript2015 (alias ES6) en utilisant le nouveau pour de boucle . Par exemple, ce code n'imprime pas les éléments du tableau après le numéro 5:

let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let el of arr) {
  console.log(el);
  if (el === 5) {
    break;
  }
}

à Partir de la documentation:

à la fois pour...dans et pour...des déclarations itèrent sur quelque chose. La principale différence entre eux est ce qu'ils itérer sur. La déclaration pour ... dans itère au-dessus des propriétés énumérables d'un objet, dans l'ordre d'insertion original. Le pour...de l'énoncé itère sur les données que l'objet itérable définit pour être itéré.

besoin de l'indice dans l'itération? Vous pouvez utiliser Array.entries() :

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}
184
répondu canac 2018-05-15 14:00:16
la source

vous pouvez utiliser chaque méthode:

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

pour l'utilisation de l'ancienne prise en charge du navigateur:

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

plus de détails ici .

156
répondu Valdemar_Rudolfovich 2012-07-19 13:18:49
la source

citant la documentation MDN de Array.prototype.forEach() :

Il y a aucun moyen de les arrêter ou de les casser un forEach() boucle autre que par la levée d'une exception. Si vous avez besoin d'un tel comportement, la méthode .forEach() est la mauvais outil , utilisez une boucle simple à la place. Si vous testez les éléments du tableau pour un prédicate et besoin d'une valeur de retour booléenne, vous pouvez utiliser every() ou some() à la place.

pour votre code (dans la question), comme suggéré par @bobince, utilisez Array.prototype.some() à la place. Il convient très bien à votre cas d'utilisation.

Array.prototype.some() exécute la fonction de rappel une fois pour chaque élément présent dans le tableau jusqu'à ce qu'il trouve un où callback renvoie une valeur truthy (une valeur qui devient true lorsqu'elle est convertie en Boolean ). Si un tel élément est trouvé, some() retourne immédiatement true. Sinon, some() retourne false. la fonction de rappel n'est invoquée que pour les index du tableau qui ont des valeurs attribuées; elle n'est pas invoquée pour les index qui ont été supprimés ou qui n'ont jamais reçu de valeurs.

46
répondu Rahul Desai 2018-05-02 21:54:03
la source

Malheureusement, dans ce cas, il sera beaucoup mieux si vous n'utilisez pas forEach . À la place, utilisez une boucle for et elle fonctionnera exactement comme vous vous y attendiez.

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}
42
répondu Weston Ganger 2017-12-08 00:18:10
la source

envisager d'utiliser la méthode jquery s each , car elle permet de retourner la fonction false inside callback:

$.each(function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

Lodash bibliothèques fournit également 151980920" takeWhile méthode qui peut être enchaîné avec map/reduce/fold etc:

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];

_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']

// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']

// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']

// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []
24
répondu vittore 2017-04-18 14:18:24
la source

si vous souhaitez utiliser suggestion de Dean Edward et jeter l'erreur D'arrêt pour sortir de la boucle sans avoir à attraper l'erreur, vous pouvez utiliser la fonction suivante ( à l'origine d'ici ):

// Use a closure to prevent the global namespace from be polluted.
(function() {
  // Define StopIteration as part of the global scope if it
  // isn't already defined.
  if(typeof StopIteration == "undefined") {
    StopIteration = new Error("StopIteration");
  }

  // The original version of Array.prototype.forEach.
  var oldForEach = Array.prototype.forEach;

  // If forEach actually exists, define forEach so you can
  // break out of it by throwing StopIteration.  Allow
  // other errors will be thrown as normal.
  if(oldForEach) {
    Array.prototype.forEach = function() {
      try {
        oldForEach.apply(this, [].slice.call(arguments, 0));
      }
      catch(e) {
        if(e !== StopIteration) {
          throw e;
        }
      }
    };
  }
})();

le code ci-dessus vous donnera la possibilité d'exécuter du code tel que le suivant sans avoir à faire vos propres clauses d'essai:

// Show the contents until you get to "2".
[0,1,2,3,4].forEach(function(val) {
  if(val == 2)
    throw StopIteration;
  alert(val);
});

un important chose à retenir, c'est que cela ne fera que mettre à jour le Tableau.prototype.pour chaque fonction si elle existe déjà. Si elle n'existe pas déjà, il ne modifiera pas la.

14
répondu Chris West 2011-07-05 23:32:16
la source

de votre exemple de code, il ressemble à Array.prototype.find est ce que vous recherchez: tableau.prototype.find() et "151950920 Tableau.prototype.findIndex ()

[1, 2, 3].find(function(el) {
    return el === 2;
}); // returns 2
13
répondu Oliver Moran 2017-04-04 11:28:41
la source

brève réponse: utilisez for...break pour cela ou changez votre code pour éviter de casser forEach . N'utilisez pas .some() ou .every() pour émuler for...break . Réécrivez votre code pour éviter la boucle for...break , ou utilisez for...break . Chaque fois que vous utilisez ces méthodes comme for...break alternative Dieu tue le chaton.

longue réponse:

.some() et .every() les deux retournent boolean valeur, .some() retours true s'il y a un élément pour lequel la fonction passée retourne true , chaque retour false s'il y a un élément pour lequel la fonction passée retourne false . C'est ce que les fonctions de la moyenne. Utiliser des fonctions pour ce qu'elles ne veulent pas dire est bien pire que d'utiliser des tables pour la mise en page au lieu de CSS, parce que cela frustre tous ceux qui lisent votre code.

Aussi, la seule façon possible d'utiliser ces méthodes comme for...break alternative est de faire les effets secondaires (changer quelques var en dehors de la fonction de rappel .some() ), et ce n'est pas très différent de for...break .

donc, en utilisant .some() ou .every() comme for...break boucle alternative n'est pas libre d'effets secondaires , ce n'est pas beaucoup plus propre que for...break , c'est frustrant, donc ce n'est pas mieux.

vous pouvez toujours réécrire votre code pour qu'il n'y ait pas besoin dans for...break . Vous pouvez filtrer les tableaux en utilisant .filter() , vous pouvez diviser le tableau en utilisant .slice() et ainsi de suite, puis utiliser .forEach() ou .map() pour cette partie du tableau.

8
répondu Max 2013-07-29 16:34:28
la source

a trouvé cette solution sur un autre site. Vous pouvez envelopper l'avant-bras dans un scénario d'essai / capture.

if(typeof StopIteration == "undefined") {
 StopIteration = new Error("StopIteration");
}

try {
  [1,2,3].forEach(function(el){
    alert(el);
    if(el === 1) throw StopIteration;
  });
} catch(error) { if(error != StopIteration) throw error; }

plus de détails ici: http://dean.edwards.name/weblog/2006/07/enum /

3
répondu RussellUresti 2010-04-15 02:12:12
la source

si vous n'avez pas besoin d'accéder à votre tableau après itération, vous pouvez sauter en définissant la longueur du tableau à 0. Si vous en avez encore besoin après votre itération, vous pouvez le cloner en utilisant slice..

[1,3,4,5,6,7,8,244,3,5,2].forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

ou avec un clone:

var x = [1,3,4,5,6,7,8,244,3,5,2];

x.slice().forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

qui est une bien meilleure solution que de lancer des erreurs aléatoires dans votre code.

3
répondu 3rdEden 2014-09-18 16:24:15
la source

C'est une boucle, mais maintient la référence de l'objet dans la boucle comme un forEach (), mais vous pouvez sortir.

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}
3
répondu jamos 2017-10-19 12:54:09
la source

C'est juste quelque chose que j'ai trouvé pour résoudre le problème... Je suis assez sûr qu'il corrige le problème que l'asker original avait:

Array.prototype.each = function(callback){
    if(!callback) return false;
    for(var i=0; i<this.length; i++){
        if(callback(this[i], i) == false) break;
    }
};

Et alors vous l'appelleriez en utilisant:

var myarray = [1,2,3];
myarray.each(function(item, index){
    // do something with the item
    // if(item != somecondition) return false; 
});

retourner false à l'intérieur de la fonction callback causera une interruption. Laissez-moi savoir si cela ne fonctionne pas réellement.

2
répondu tennisgent 2013-02-20 20:54:54
la source

j'utilise nullhack dans ce but, il tente d'accéder à la propriété null , ce qui est une erreur:

try {
  [1,2,3,4,5]
  .forEach(
    function ( val, idx, arr ) {
      if ( val == 3 ) null.NULLBREAK;
    }
  );
} catch (e) {
  // e <=> TypeError: null has no properties
}
//
2
répondu public override 2014-01-06 02:42:19
la source

un autre concept que j'ai inventé:

function forEach(array, cb) {
  var breakOnNext = false;
  function _break() { breakOnNext = true; }
  for (var i = 0, bound = array.length; i < bound; ++i) {
    if (breakOnNext) { break; }
    cb(array[i], i, array, _break);
  }
}

Utilisation:

forEach(['a','b','c','d'], function (e, i, array, _break) {
  console.log(e, i);
  if (e === 'b') { _break(); }
});

pourrait avoir besoin de quelques retouches, en particulier pour supporter l'itération des propriétés de l'objet.

2
répondu c24w 2014-02-02 02:24:03
la source

si vous voulez garder votre syntaxe forEach , c'est une façon de le garder efficace (bien que pas aussi bon qu'un régulier pour boucle). Vérifier immédiatement pour une variable qui sait si vous voulez sortir de la boucle.

cet exemple utilise une fonction anonyme pour créer un champ de fonction autour du forEach dont vous avez besoin pour stocker les informations fait .

(function(){
    var element = document.getElementById('printed-result');
    var done = false;
    [1,2,3,4].forEach(function(item){
        if(done){ return; }
        var text = document.createTextNode(item);
        element.appendChild(text);
        if (item === 2){
          done = true;
          return;
        }
    });
})();
<div id="printed-result"></div>

mes deux cents.

1
répondu Justus Romijn 2015-09-24 15:40:48
la source

comme mentionné ci-dessus, vous ne pouvez pas briser .forEach() .

Voici une façon un peu plus moderne de faire un foreach avec des itérateurs ES6. Vous permet d'obtenir un accès direct à index / value lors de l'itération.

const array = ['one', 'two', 'three'];

for (const [index, val] of array.entries()) {
  console.log('item:', { index, val });
  if (index === 1) {
    console.log('break!');
    break;
  }
}

sortie:

item: { index: 0, val: 'one' }
item: { index: 1, val: 'two' }
break!

Liens

1
répondu Alex 2017-12-14 14:58:54
la source

utilisez la fonction array.prototype.every , qui vous fournissent l'utilité de briser la boucle. Voir l'exemple ici documentation Javascript sur Mozilla developer network

0
répondu Yiling 2015-05-02 10:38:30
la source

D'accord avec @bobince, en minorité.

Aussi, pour info:

Prototype.js a quelque chose dans ce but:

<script type="text/javascript">
  $$('a').each(function(el, idx) {
    if ( /* break condition */ ) throw $break;
    // do something
  });
</script>

$break sera catché et manipulé par Prototype.JS en interne, rompant le cycle" chaque " mais ne générant pas d'erreurs externes.

Voir Prototype.JS API pour plus de détails.

jQuery a aussi un moyen, il suffit de retourner false dans le gestionnaire de briser la boucle au début:

<script type="text/javascript">
  jQuery('a').each( function(idx) {
    if ( /* break condition */ ) return false;
    // do something

  });
</script>

Voir jQuery API pour plus de détails.

0
répondu Dmitri Sologoubenko 2015-08-18 18:37:21
la source

ce n'est pas le plus efficace, puisque vous faites encore tourner tous les éléments, mais j'ai pensé qu'il pourrait être intéressant de considérer le très simple:

let keepGoing = true;
things.forEach( (thing) => {
  if (noMore) keepGoing = false;
  if (keepGoing) {
     // do things with thing
  }
});
0
répondu martyman 2015-12-18 00:52:51
la source

, vous pouvez suivre le code ci-dessous qui fonctionne pour moi:

 var     loopStop = false;
YOUR_ARRAY.forEach(function loop(){
    if(loopStop){ return; }
    if(condition){ loopStop = true; }
});
0
répondu BERGUIGA Mohamed Amine 2016-08-30 14:06:27
la source

Je ne le sais pas de la bonne façon. Il n'est pas casser la boucle. C'est un Jugad

let result = true;
[1, 2, 3].forEach(function(el) {
    if(result){
      console.log(el);
      if (el === 2){
        result = false;
      }
    }
});
0
répondu Durgpal Singh 2017-07-20 12:41:23
la source

je préfère utiliser for in

var words = ['a', 'b', 'c'];
var text = '';
for (x in words) {
    if (words[x] == 'b') continue;
    text += words[x];
}
console.log(text);

for in fonctionne un peu comme forEach , et vous pouvez ajouter la fonction de retour à la sortie à l'intérieur. De meilleures performances.

0
répondu Jorge Alberto 2017-08-04 01:08:27
la source

si vous avez besoin de casser basé sur la valeur des éléments qui sont déjà dans votre tableau comme dans votre cas (c.-à-d. si la condition de rupture ne dépend pas de la variable de temps d'exécution qui peut changer après que le tableau est assigné ses valeurs d'élément) vous pouvez également utiliser la combinaison de tranche () et indexOf () comme suit.

si vous avez besoin de briser quand forEach atteint "Apple", vous pouvez utiliser

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var fruitsToLoop = fruits.slice(0, fruits.indexOf("Apple"));
// fruitsToLoop = Banana,Orange,Lemon

fruitsToLoop.forEach(function(el) {
    // no need to break
});

comme indiqué W3Schools.com la méthode slice() retourne les éléments sélectionnés dans un tableau, comme un nouvel objet array. Le tableau d'origine ne sera pas changé.

le Voir dans JSFiddle

J'espère que ça aidera quelqu'un.

0
répondu Ula 2018-07-18 17:19:23
la source

essayez avec "trouver" :

var myCategories = [
 {category: "start", name: "Start", color: "#AC193D"},
 {category: "action", name: "Action", color: "#8C0095"},
 {category: "exit", name: "Exit", color: "#008A00"}
];

function findCategory(category) {
  return myCategories.find(function(element) {
    return element.category === category;
  });
}

console.log(findCategory("start"));
// output: { category: "start", name: "Start", color: "#AC193D" }
0
répondu GigolNet Guigolachvili 2018-08-07 11:11:56
la source

la bonne réponse dépend de pourquoi vous voulez faire cela.

si ce que vous voulez est: "aussi propre et concis que possible une façon de sortir de forEach() étant donné que break n'est pas autorisé " alors vous pouvez redéfinir tableau.forEach() pour vous permettre de faire ceci:

[1,2,3,4,5].forEach((x,i,stop) => { // x and i are the standard 2 args
  if (x > 3) {
    stop() // You could call it 'end', 'brk' or whatever...
  }
  console.log(x)
})

voici le surpassement, notez que forEach() passe normalement deux paramètres: l'objet itéré actuellement, et index. Nous n'en ajoutons qu'un troisième:

Array.prototype.forEach = function(fn) {
  var StopIteration = new Error("StopIteration");
  var len = this.length;
  function stop() {
    throw StopIteration;
  }
  for (i=0;i<len;i++) {
    try {
      fn(this[i], i, stop)
    } 
    catch(e) {
      if(e == StopIteration) {
        return
      }
      throw e;
    }
  }
}

vous pouvez utiliser n'importe quel nom que vous aimez (sauf break , ou n'importe quel autre mot-clé réservé, pas de chance là!)

(sur un vrai projet, vous devriez aller avec l'une des réponses Super upvoted. J'ajoute simplement ceci parce que certaines personnes pourraient trouver le concept utile dans d'autres applications).

0
répondu andyhasit 2018-09-02 00:07:45
la source

encore une autre approche

        var wageType = types.filter(function(element){
            if(e.params.data.text == element.name){ 
                return element;
            }
        });
        console.dir(wageType);
0
répondu Harry Bosh 2018-10-03 04:05:09
la source
var Book = {"Titles":[                          
    {
    "Book3" : "BULLETIN 3"
    }   
    ,
    {
    "Book1" : "BULLETIN 1"
    }
    ,
    {
    "Book2" : "BULLETIN 2"
    }    
]}

var findbystr = function(str) { 
    var return_val;
    Book.Titles.forEach(function(data){ 
        if(typeof data[str] != 'undefined')
        {
            return_val = data[str];
        } 
    }, str) 

    return return_val;
}

book = findbystr('Book1');
console.log(book);
-1
répondu Samuel Gray 2015-04-29 13:16:34
la source

Autres questions sur javascript arrays