2012-09-25 1 views
15
List data = [1, 2, 3]; 
data.forEach((value) { 
    if (value == 2) { 
    // how to stop? 
    } 
    print(value); 
}); 

Ich versuchte return false;, die in jQuery funktioniert, aber es funktioniert nicht in Dart. Gibt es eine Möglichkeit, es zu tun?Wie man Dart's .forEach() stoppt?

+0

Was bedeutet "nicht funktioniert" bedeuten? Was macht es eigentlich? –

+0

Es tut nichts. – Leksat

+0

Wenn Sie sagen, dass dies in JavaScript funktioniert, meinen Sie in einer Bibliothek wie jQuery? Ich frage, weil es so aussieht, als ob der hier beschriebene Algorithmus bei einem Rückgabewert von "false" nicht bricht: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach Überlegen Sie, ob Sie a Fehler, wenn Sie diese Funktion wünschen. –

Antwort

16

können Sie auch eine Verwendung für/in, die implizit den Iterator verwendet treffend in der anderen Antwort demonstriert:

List data = [1,2,3]; 

for(final i in data){ 
    print('$i'); 
    if (i == 2){ 
    break; 
    } 
} 
+0

Die folgende "takeWhile()" - Lösung nutzt die Vorteile neuerer Dart-Änderungen und ist wahrscheinlich in den meisten Fällen eine bessere Lösung. –

8

Der Rückruf, den forEach ausführt, gibt void zurück, sodass es keinen Mechanismus gibt, die Iteration zu stoppen. In diesem Fall

sollten Sie Iteratoren werden:

void listIteration() { 
    List data = [1,2,3]; 

    Iterator i = data.iterator(); 

    while (i.hasNext()) { 
    var e = i.next(); 
    print('$e'); 
    if (e == 2) { 
     break; 
    } 
    } 
} 
2

Dart tut unterstützen nicht-lokale Rückgaben, so dass die Rückkehr von einem Rückruf die Schleife nicht unterbricht. Der Grund, warum es in jQuery funktioniert, ist, dass each() den vom Callback zurückgegebenen Wert überprüft. Dart forJeder Callback gibt void zurück.

http://docs.jquery.com/Core/each

7

Brechen ein List

List<int> example = [ 1, 2, 3 ]; 

for (int value in example) { 
    if (value == 2) { 
    break; 
    } 
} 

Brechen ein Map

Wenn Sie mit einem Map es zu tun Sie nicht einfach einen Iterator aus der angegebenen Karte bekommen, aber Sie können Verwenden Sie immer noch for, indem Sie sie entweder auf die Werte oder die Schlüssel anwenden. Da Sie manchmal die Kombination beider Schlüssel und Werte könnten benötigen, ist hier ein Beispiel:

Map<String, int> example = { 'A': 1, 'B': 2, 'C': 3 }; 

for (String key in example.keys) { 
    if (example[key] == 2 && key == 'B') { 
    break; 
    } 
} 

Beachten Sie, dass eine Karte unbedingt sie Schlüssel nicht haben als [ 'A', 'B', 'C' ] eine LinkedHashMap verwenden, wenn Sie das wollen. Wenn Sie nur die Werte möchten, tun Sie einfach example.values statt example.keys.

Alternativ, wenn Sie nur für ein Element suchen, können Sie alles vereinfachen zu:

List<int> example = [ 1, 2, 3 ]; 
int matched = example.firstMatching((e) => e == 2, orElse:() => null); 
11

Es ist auch möglich, Ihr Beispiel mit foreach() und Takewhile() zu implementieren.

var data = [1, 2, 3]; 
data.takeWhile((val) => val != 2).forEach(print); 
+0

.TakeWhile() war nicht da, als ich die ursprüngliche Antwort gepostet habe. Ich würde sagen, dass es für die meisten Fälle jetzt ein geeigneterer und eleganterer Ansatz ist. –