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?

Molliger Junge
quelle
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;
    }
  }
});
dnc253
quelle
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.');
}
Nishchit Dhanani
quelle
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/

Neo Vijay
quelle
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

Aman Fahimullah
quelle
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

mna
quelle
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
conceptdeluxe
quelle
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.

Victor Aguilar
quelle
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;
  }
});
Panatoni
quelle
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/

Nik Dow
quelle
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.')
    }

Downhillski
quelle
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
                  }
                });
rb4bhushan
quelle
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]);
}
endrcn
quelle
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)
            }

        }      
    });
});
user1693371
quelle
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;
     });
 }
Solanki ...
quelle
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.

PrabaharanKathiresan
quelle
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.

Küstenlinie
quelle
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;
  }
}
Maikel Rosabal
quelle
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;
  }
});
Shanmugarajan
quelle
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;
    }
}
poovarasi sekar
quelle
-1

Ich würde returnanstelle von verwenden break.

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

Klappt wunderbar.

Aakash
quelle
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
     }
}
Sultan
quelle
OP will aus der Schleife ausbrechen.
Angel S. Moreno