Angular JS break ForEach


256

Ich habe eine eckige foreach-Schleife und möchte von der Schleife abbrechen, wenn ich mit einem Wert übereinstimme. Der folgende Code funktioniert nicht.

angular.forEach([0,1,2], function(count){
  if(count == 1){
    break;
  }
});

Wie kann ich das bekommen?


1
Ich verstehe nicht, warum Sie den Wert nicht einfach finden, anstatt in eine Schleife zu gehen. Vielleicht erzählt das Beispiel, das Sie gegeben haben, nicht die ganze Geschichte, aber ich würde lieber das tun, was @Aman unten gesagt hat. Warum in die Schleife gehen, wie unten erwähnt, und jedes Mal eine Überprüfung durchführen, wenn some () genau das auf elegantere Weise tut? Denken Sie daran, dass es keinen Sinn machen sollte, diese für Kontrollstrukturen vom Typ / while / break zu verwenden, wenn Sie Javascript als funktionale Sprache behandeln. Deshalb gibt es Foreach, Find, einige usw.
Adrian Rodriguez

Antworten:


264

Es gibt keine Möglichkeit, dies zu tun. Siehe https://github.com/angular/angular.js/issues/263 . Je nachdem, was Sie tun, können Sie einen Booleschen Wert verwenden, um nicht in den Körper der Schleife zu gelangen. Etwas wie:

var keepGoing = true;
angular.forEach([0,1,2], function(count){
  if(keepGoing) {
    if(count == 1){
      keepGoing = false;
    }
  }
});

45
Ich würde lieber einfach ein !keepGoing && return;am Anfang der Funktion hinzufügen , weniger Code.
Andrew Joslin

46
Dies ist keine bewährte Methode. Hier wird der Winkel für jede Schleife niemals unterbrochen, und es gibt nichts, was für jeden Winkel unterbrochen werden kann. Native for loop ist ungefähr 90% schneller als angle.forEach. Daher ist es besser, native for-Schleife zu verwenden, wenn Sie die Bedingungsübereinstimmung unterbrechen möchten. Danke
Nishchit Dhanani

xcatly wo ich feststeckte ... und das half ... vielen Dank ... Wie auch immer, ich würde gerne wissen, warum jede Schleife unzerbrechlich ist. Wenn überhaupt
Saurabh Tiwari

Dies sollte nicht die akzeptierte Antwort sein, da dadurch die forEach-Schleife nicht unterbrochen wird. Es ist nur eine Möglichkeit, nicht die gesamte Logik innerhalb der Schleife auszuführen.
Nebulosar

296

Das angular.forEach Schleife kann bei einer Bedingungsübereinstimmung nicht unterbrochen werden.

Mein persönlicher Rat ist, stattdessen eine NATIVE FOR- Schleife zu verwenden angular.forEach.

Die NATIVE FOR-Schleife ist etwa 90% schneller als andere for-Schleifen.

Für Schleifenunterbrechung, für Schleifentestergebnis

GEBRAUCH FÜR FOR-Schleife IN ANGULAR:

var numbers = [0, 1, 2, 3, 4, 5];

for (var i = 0, len = numbers.length; i < len; i++) {
  if (numbers[i] === 1) {
    console.log('Loop is going to break.'); 
    break;
  }
  console.log('Loop will continue.');
}

1
Das funktioniert bei mir nicht. Alles, was es tut, ist diese spezielle Iteration der Schleife zu beenden. Aber dann geht es weiter zur nächsten Iteration.
Ben

1
@ Ben, Sorry ben, es war mein Fehler, aber jetzt aktualisiere ich meine Antwort nach langer Recherche. Ich hoffe, dies wird dir helfen . Vielen Dank
Nishchit Dhanani

1
@LGama: - Was ist dein Fall?
Nishchit Dhanani

3
jsperf.com/angular-foreach-performance Testen Sie es in Ihrem eigenen Browser, um zu entscheiden, welche Funktion Sie wählen sollten. Ich habe auf IE11 getestet und es ist auch so schnell wie im Screenshot. Auch Array.some () getestet, aber es ist langsamer als Array.forEach () auf IE11, könnte aber schneller sein als angle.foreach ;-). Oder testen Sie es hier jsperf.com/angular-foreach-vs-native (alle Credits gehen an den ursprünglichen Autor, nicht an mich ;-))
Sebastian

6
Selbst mit jsperf kann man nicht sagen, dass "native for ungefähr 90% schneller ist". In Ihrem Szenario hängt dies stark davon ab, wie teuer die Ausführung der inneren Funktion ist und wie viele Ausführungen durch frühzeitiges Verlassen der Schleife (Pause) gespeichert werden können.
hgoebl

22

Bitte verwenden Sie einige oder alle Instanzen von ForEach.

Array.prototype.some:
some is much the same as forEach but it break when the callback returns true

Array.prototype.every:
every is almost identical to some except it's expecting false to break the loop.

Beispiel für einige:

var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

ary.some(function (value, index, _ary) {
    console.log(index + ": " + value);
    return value === "JavaScript";
});

Beispiel für jeden:

var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

ary.every(function(value, index, _ary) {
    console.log(index + ": " + value);
    return value.indexOf("Script") > -1;
});

Weitere Informationen finden Sie unter
http://www.jsnoob.com/2013/11/26/how-to-break-the-foreach/


no @ AngelS.Moreno, jeder bevorzugt die Verwendung einer lokalen Variablen anstelle einer Methode, die speziell für den vorliegenden Fall entwickelt wurde
Oded Niv

18

Verwenden Sie die Array Some-Methode

 var exists = [0,1,2].some(function(count){
      return count == 1
 });

exist gibt true zurück und Sie können dies als Variable in Ihrer Funktion verwenden

if(exists){
    console.log('this is true!')
}

Array Einige Methode - Javascript


4
Für mich ist der einzige Grund zu verwenden, angular.forEach()dass ich IE8 unterstützen muss, das nicht hat Array.forEach()... oder Array.some().
Bennett McElwee

2
Sie können Array.forEach einfach polyfill. Siehe unten auf der Seite: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
zumalifeguard

6

Soweit ich weiß, bietet Angular eine solche Funktion nicht an. Möglicherweise möchten Sie hierfür die find()Funktion des Unterstrichs verwenden (es handelt sich im Grunde genommen um ein forEach, das aus der Schleife ausbricht, sobald die Funktion true zurückgibt).

http://underscorejs.org/#find


Dies könnte das Problem seitlich lösen, aber es bricht nicht in der Tat die Schleife.
Elise Chant

Oder native for - Schleife
shanti

6

Wenn Sie jQuery (daher nicht jqLite) in Verbindung mit AngularJS verwenden, können Sie mit $ .each iterieren. Dies ermöglicht das Unterbrechen und Fortfahren basierend auf dem booleschen Rückgabewertausdruck.

JSFiddle:

http://jsfiddle.net/JEcD2/1/

Javascript:

var array = ['foo', 'bar', 'yay'];
$.each(array, function(index, element){
    if (element === 'foo') {
        return true; // continue
    }
    console.log(this);
    if (element === 'bar') {
        return false; // break
    }
});

Hinweis:

Obwohl die Verwendung von jQuery nicht schlecht ist, werden von MDN sowohl native Array.some- als auch Array.every- Funktionen empfohlen, wie Sie in der nativen forEach- Dokumentation lesen können :

"Es gibt keine Möglichkeit, eine forEach-Schleife anzuhalten oder zu unterbrechen. Die Lösung besteht darin, Array.every oder Array.some zu verwenden."

Folgende Beispiele werden von MDN bereitgestellt:

Array.some:

function isBigEnough(element, index, array){
    return (element >= 10);
}
var passed = [2, 5, 8, 1, 4].some(isBigEnough);
// passed is false
passed = [12, 5, 8, 1, 4].some(isBigEnough);
// passed is true

Array.every:

function isBigEnough(element, index, array){
    return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed is true

6

Konkret können Sie eine forEachSchleife verlassen und an jedem Ort eine Ausnahme auslösen.

try {
   angular.forEach([1,2,3], function(num) {
      if (num === 2) throw Error();
   });
} catch(e) {
    // anything
}

Es ist jedoch besser, wenn Sie eine andere Bibliothek verwenden oder Ihre eigene Funktion implementieren, findin diesem Fall eine Funktion, damit Ihr Code auf höchstem Niveau ist.


10
Nun, du hast die Frage beantwortet! Ich hoffe das macht aber niemand :)
Jason Cox

Das unnötige Auslösen einer Ausnahme ist kein guter Weg, um mit der Situation umzugehen. Überprüfen Sie lieber die Lösung von @ dnc253 stackoverflow.com/a/13844508/698127
Aamol

4

Versuchen Sie dies als Pause;

angular.forEach([0,1,2], function(count){
  if(count == 1){
    return true;
  }
});

3

Wie in den anderen Antworten angegeben, bietet Angular diese Funktionalität nicht an. jQuery funktioniert jedoch, und wenn Sie jQuery sowie Angular geladen haben, können Sie verwenden

jQuery.each ( array, function ( index, value) {
    if(condition) return false; // this will cause a break in the iteration
})

Siehe http://api.jquery.com/jquery.each/


2
Das OP bat um eine AngularJS-Lösung, die richtige Antwort ist NEIN :)
Shannon Hochkins

3

Normalerweise gibt es keine Möglichkeit, eine "jede" Schleife in Javascript zu unterbrechen. Was normalerweise getan werden kann, ist die Verwendung der "Kurzschluss" -Methode.

    array.forEach(function(item) {
      // if the condition is not met, move on to the next round of iteration.
      if (!condition) return;

      // if the condition is met, do your logic here
      console.log('do stuff.')
    }


2

break ist nicht in eckigem forEach zu erreichen, wir müssen forEach modifizieren, um das zu tun.

$scope.myuser = [{name: "Ravi"}, {name: "Bhushan"}, {name: "Thakur"}];  
                angular.forEach($scope.myuser, function(name){
                  if(name == "Bhushan") {
                    alert(name);
                    return forEach.break(); 
                    //break() is a function that returns an immutable object,e.g. an empty string
                  }
                });

Diese Antwort scheint nicht vollständig zu sein. Bitte geben Sie an, ob break()definiert werden muss oder ob es bereits Teil des Winkels ist. Bitte definieren Sie, wenn nicht.
Geoidesic

2

Sie können dies verwenden:

var count = 0;
var arr = [0,1,2];
for(var i in arr){
   if(count == 1) break;
   //console.log(arr[i]);
}

1
var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];
var keepGoing = true;
ary.forEach(function(value, index, _ary) {
    console.log(index)
    keepGoing = true;
    ary.forEach(function(value, index, _ary) {
        if(keepGoing){ 
            if(index==2){
                keepGoing=false;
            }
            else{
                console.log(value)
            }

        }      
    });
});

0
$scope.arr = [0, 1, 2];  
$scope.dict = {}
for ( var i=0; i < $scope.arr.length; i++ ) {
    if ( $scope.arr[i] == 1 ) {
        $scope.exists = 'yes, 1 exists';
        break;
    }
 }
 if ( $scope.exists ) {
     angular.forEach ( $scope.arr, function ( value, index ) {
                      $scope.dict[index] = value;
     });
 }

0

Ich würde es vorziehen, dies im Gegenzug zu tun. Setzen Sie den Schleifenteil in die private Funktion und kehren Sie zurück, wenn Sie die Schleife unterbrechen möchten.


0

Mir ist klar, dass dies alt ist, aber ein Array-Filter kann genau das tun, was Sie brauchen:

var arr = [0, 1, 2].filter(function (count) {
    return count < 1;
});

Sie können dann arr.forEachund andere Array-Funktionen ausführen .

Mir ist klar, dass wenn Sie beabsichtigen, die Schleifenoperationen insgesamt zu reduzieren, dies wahrscheinlich nicht das tut, was Sie wollen. Dafür verwenden Sie am besten while.


0

Dieses Beispiel funktioniert. Versuch es.

var array = [0,1,2];
for( var i = 0, ii = array.length; i < ii; i++){
  if(i === 1){
   break;
  }
}

1
Ich denke, dass er keine forSchleife will , sein Anwendungsfall braucht eine foreachnicht forwahrscheinlich
Hassen Ch.

0

Verwenden Sie Return, um die Schleife zu unterbrechen.

angular.forEach([0,1,2], function(count){
  if(count == 1) {
    return;
  }
});

0
onSelectionChanged(event) {
    let selectdata = event['api']['immutableService']['gridOptionsWrapper']['gridOptions']['rowData'];
    let selected_flag = 0;

    selectdata.forEach(data => {
      if (data.selected == true) {
        selected_flag = 1;
      }
    });

    if (selected_flag == 1) {
      this.showForms = true;
    } else {
      this.showForms = false;
    }
}

-1

Ich würde returnanstelle von verwenden break.

angular.forEach([0,1,2], function(count){
  if(count == 1){
    return;
  }
});

Klappt wunderbar.


Dies ist keine gültige Lösung. look: function test () {angle.forEach ([1,2,3,4,5,6,7,8,9], function (value, index) {if (value == 2) return; console.log (Wert);})} Ausgabe:> teste (); 1 3 4 5 6 7 8 9
otaviodecampos

-2

Fügen Sie einfach $ index hinzu und gehen Sie wie folgt vor:

angular.forEach([0,1,2], function(count, $index) {
     if($index !== 1) {
          // do stuff
     }
}

OP will aus der Schleife ausbrechen.
Angel S. Moreno
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.