如何跳过“ foreach”循环的迭代?


324

在Perl中,我可以使用next;命令跳过foreach(或任何循环)迭代。

有没有办法跳过迭代并跳转到C#中的下一个循环?

 foreach (int number in numbers)
 {
     if (number < 0)
     {
         // What goes here to skip over the loop?
     }

     // otherwise process number
 }

通知用户输入错误与跳过输入一样重要!
有用蜜蜂

Answers:


664

你要:

foreach (int number in numbers) //   <--- go back to here --------+
{                               //                                |
    if (number < 0)             //                                |
    {                           //                                |
        continue;   // Skip the remainder of this iteration. -----+
    }

    // do work
}

这是有关continue关键字的更多信息。


更新:在评论中回应Brian的后续问题:

您能否进一步阐明如果嵌套了for循环并想跳过扩展循环之一的迭代该怎么办?

for (int[] numbers in numberarrays) {
  for (int number in numbers) { // What to do if I want to
                                // jump the (numbers/numberarrays)?
  }
}

A continue始终适用于最近的封闭范围,因此您不能使用它来突破最外层的循环。如果出现这样的情况,则需要根据实际需要执行更复杂的操作,例如break从内部循环continue到外部循环。有关break关键字的文档,请参见此处。在breakC#的关键字是类似于Perl的last关键字。

另外,考虑采用达斯汀(Dustin)的建议,只过滤掉您不想预先处理的值:

foreach (var basket in baskets.Where(b => b.IsOpen())) {
  foreach (var fruit in basket.Where(f => f.IsTasty())) {
    cuteAnimal.Eat(fruit); // Om nom nom. You don't need to break/continue
                           // since all the fruits that reach this point are
                           // in available baskets and tasty.
  }
}

您能否进一步阐明如果嵌套了循环并想跳过扩展循环之一的迭代该怎么办?例如:for(int [] numberarrays中的数字){for(int innumber中的数字){//如果要跳过(numbers / numberarrays)怎么办}}
布莱恩(Brian

C#goto实际上对于@Brian询问的情况很有用。nextArray:在外部循环的底部添加一个标签,然后goto nextArray;在要跳过时添加标签。
雅各布·克拉尔

55

另一种方法是在循环执行之前使用LINQ进行过滤:

foreach ( int number in numbers.Where(n => n >= 0) )
{
    // process number
}

2
+1。尽管这不是对问题的直接回答,但实际上,我可能更喜欢此解决方案,而不是我提出的解决方案。使用LINQ似乎是一个很好的通用用例,用于过滤出您不想处理的循环值。
约翰·费米内拉

3
这只是比较整齐,还是实际上会更快,因为要进行的教学更少?我猜想LINQ进行了很大的优化,但是LINQ部分必须在某个时候进行取整,因此从理论上讲,如果数据集很大并且生成的“已过滤”子集几乎一样大,那么这将变慢,因为需要进行取整两次?因此,也许取决于预期的结果子数据集?
Coops 2012年

25

您还可以翻转if测试:


foreach ( int number in numbers )
{
     if ( number >= 0 )
     {
        //process number
     }
 }

:) 谢谢!我想出一个基本的示例,因为在循环开始时有一些准则不需要处理,而其他准则则是必须捕获的错误。
布赖恩2009年

4
一个基于LINQ的答案很好,也很优雅,但是使用if语句并没有错。
crashmstr 2011年


16

您可以使用该continue语句。

例如:

foreach(int number in numbers)
{
    if(number < 0)
    {
        continue;
    }
}

16

使用linq的另一种方法是:

foreach ( int number in numbers.Skip(1))
{   
    // process number  
}

如果要跳过多个项目中的第一个项目。

或者,.SkipWhere如果要指定跳过条件,请使用。


这是最简单的方法(尽管内部逻辑可能是相同的),因为您现在可以使用Linq。尽管您应该确保由于性能原因仅调用一次.Skip。(是的,我现在看到这不是对OP问题的直接答案,尽管是此答案列表的重要补充)。+1
B查尔斯·H(Charles H)

8

使用继续语句:

foreach(object number in mycollection) {
     if( number < 0 ) {
         continue;
     }
  }

3
不明白为什么要投票,这是错误的,因为他在“ o”而不是“ number”上循环
财富

同意,也许这是先前答案的副本/粘贴内容?从概念上讲,这是很有价值的,但请确保变量一致。
Antonio Ciolino

0

最简单的方法如下:

//Skip First Iteration

foreach ( int number in numbers.Skip(1))

//Skip any other like 5th iteration

foreach ( int number in numbers.Skip(5))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.