【问题标题】:How to stop Dart's .forEach()?如何停止 Dart 的 .forEach()?
【发布时间】:2012-09-25 16:15:46
【问题描述】:
List data = [1, 2, 3];
data.forEach((value) {
  if (value == 2) {
    // how to stop?
  }
  print(value);
});

我尝试了return false;,它在 jQuery 中有效,但在 Dart 中无效。 有什么办法吗?

【问题讨论】:

  • “不起作用”是什么意思?它实际上是做什么的?
  • 当你说这在 JavaScript 中有效时,你的意思是在像 jQuery 这样的库中吗?我之所以问,是因为这里概述的算法似乎不会因返回值为 false 而中断:developer.mozilla.org/en-US/docs/JavaScript/Reference/… 如果您需要此功能,请考虑提交错误。
  • 是的。你是对的。这是关于 jQuery 的。

标签: dart


【解决方案1】:

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

List data = [1,2,3];

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

【讨论】:

  • 下面的“takeWhile()”解决方案利用了最近对 Dart 的更改,在大多数情况下可能是更好的解决方案。
【解决方案2】:

也可以使用 forEach() 和 takeWhile() 来实现您的示例。

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

【讨论】:

  • .takeWhile() 在我发布原始答案时不在。我会说现在对于大多数情况来说这是一种更合适、更优雅的方法。
  • 看起来列表将被迭代两次。在大数据的情况下可能会影响性能。
  • takeWhile() 返回一个惰性 Iterable,因此只有一次迭代。但是与编写 for 循环相比,会有一些额外的函数调用开销。 JIT 可能会优化其中的一部分。在 TakeWhileIterator.moveNext() 中查看实现的核心:github.com/dart-archive/dev_compiler/blob/master/tool/input_sdk/…
【解决方案3】:

破解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);

【讨论】:

    【解决方案4】:

    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;
        }
      }
    }
    

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        根据 Greg Lowe 的帖子,我在我的项目中使用了 where 并且它也有效。

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

        【讨论】:

        • 不,它不会工作。它将仅删除值 == 2,并且 forEach 将遍历删除值之前和之后的值。
        • 但是可以通过 print(data) 检查这一行之后的数据,你会看到结果是 [1, 2, 3]
        【解决方案7】:

        使用多循环

        打破外循环

        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);
          }
        

        【讨论】:

          【解决方案8】:

          这是 for-in 循环的完整示例,接近 forEach 样式。

          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;
             } 
          } 
          

          【讨论】:

            【解决方案9】:

            您可以使用forindexOf

             for (var number in id) {
                var index = id.indexOf(number);
            
                print('Origin forEach loop');
            
                for (int i = 0; i < 1; i++) {
                  print("for loop");
                }
            
                break;
              }
            

            【讨论】:

              【解决方案10】:

              有人建议where(),但它不是具有中断功能的forEach() 的一般替代品

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

              foreach() 的功能,但与break 等效,由 any() 给出:继续循环返回 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
                });
              }
              

              【讨论】:

                【解决方案11】:

                您可以从 forEach 空返回来打破循环;

                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;
                  }
                });
                

                【讨论】:

                  猜你喜欢
                  • 2020-06-16
                  • 2011-09-09
                  • 2015-11-12
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多