How to stop Dart's .forEach()?

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

I tried return false; which works in jQuery, but it does not work in Dart. Is there a way to do it?

75035 次浏览

forEach 接受的回调返回 void,因此没有停止迭代的机制。

在这种情况下,您应该使用迭代器:

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


Iterator i = data.iterator;


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

您还可以使用 for/in,它隐含地使用了在另一个答案中恰当演示的迭代器:

List data = [1,2,3];


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

Dart 不支持非本地返回,因此从回调返回不会破坏循环。 它在 jQuery 中工作的原因是 each ()检查回调返回的值。 Dart for 每个回调返回 void。

Http://docs.jquery.com/core/each

破坏 List

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


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

破坏 Map

如果您正在处理一个 Map,您不能简单地从给定的映射获得一个迭代器,但是您仍然可以通过将它应用于值或键来使用 for。由于有时可能需要键和值的组合,这里有一个例子:

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


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

请注意,Map 不一定有键,因为如果需要的话,[ 'A', 'B', 'C' ]使用 LinkedHashMap。如果只需要这些值,只需执行 example.values而不是 example.keys

或者,如果您只是在搜索一个元素,那么您可以将所有内容简化为:

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

还可以使用 forEach ()和 takwhile ()实现示例。

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

基于 Greg Lowe 的文章,我在我的项目中使用了 where,而且它也起作用了。

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

使用多重循环

打破外环

OUTER: for (var i = 0; i < m.length; i++) {
for (var j = 0; j < m[i].length; j++) {
if (m[i][j] < 0) {
print("Negative value found at $i,$j: ${m[i][j]}");
break OUTER;
}
}
}

继续外环

  outer: for (var v in a) {
for (var w in b) {
if (w == v) continue outer;
}
print(v);
}

这里是一个完整的样本由 入伙循环,这接近 为每个人风格。

void main(){
var myList = [12, 18, 24, 63, 84,99];


myList.forEach((element) {
print(element);
if (element ==24); //break; // does not work
});


for(var element in myList) {
print(element);
if (element==24) break;
}
}

有人建议 where(),但它不是一般的替代 forEach()与破坏能力

(但是,where是问题示例中显示的用例的正确替代品。另一方面,我专注于标题中的问题)

any()给出了 foreach()的功能,但是相当于 break: 继续循环返回 false,停止返回 true; any ()的结果可以忽略。我认为它更类似于 jquery 中的 each()(但是在 dart 中为了阻止您返回 true)。

为了使用索引创建一个循环,同时考虑到循环中断的可能性,我使用了以下扩展:

extension IterableUtils<E> on Iterable<E> {


/**
Similar to Iterable.forEach() but:
- with an index argument
- with the optional capacity to break the loop, returning false
Note: as for the return clause, you can omit it, as with forEach()
*/
void forEachIndexed(Function(E element, int index) f) {
int index = 0;
for (E element in this) {
if (f(element, index) == false) break;
index++;
}
}
}

例如:

void main() {


List list = ["a", "b", "c"];


list.forEachIndexed((element, index) {
print("$index: $element");


//Optional:
if (element == "b") return false; //break
});
}

您可以从 forEach 中清空 return 来中断循环;

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


data.forEach((value) {
if (value == 2) {
_valueToBePrinted = value;
return;
}
});
// you can return something here to
// return _valueToBePrinted;
print(value);

不管怎样,你不应该..。

问题是,在整个 forEach 循环中不能返回任何内容

//This don't work
data.forEach((value) {
if (value == 2) {
_valueToBePrinted = value;
return;
}
if (value == 1) {
return value;
}
});