如何在C#中没有标志变量的情况下突破2个循环?

时间:2009-06-11 17:48:16

标签: c# syntax

作为一个简单的例子,我可以说我有以下网格,我正在寻找特定的单元格值。找到后我不再需要处理循环。

foreach(DataGridViewRow row in grid.Rows)
{
    foreach(DataGridViewCell cell in row.Cells)
    {
        if(cell.Value == myValue)
        {
            //Do Something useful
            //break out of both foreach loops.
        }
    }
}

这是如何在C#中完成的。在Java中,我可以使用一个标签来命名最外层的循环,然后打破该循环,但我似乎无法在C#中找到一个equivelant。

在c#中实现此目的的最简洁方法是什么?我知道我可以设置一个布尔标志,并在外部循环中检查它以突破那个,但它看起来太冗长了。

谢谢,

17 个答案:

答案 0 :(得分:65)

1

foreach(DataGridViewRow row in grid.Rows)
   foreach(DataGridView cell in row.Cells)
      if (cell.Value == somevalue) {
         // do stuff
         goto End;
      }
End:
   // more stuff

2

void Loop(grid) {
    foreach(row in grid.Rows)
       foreach(cell in row.Cells)
           if (something) {
               // do stuff   
               return;
           }
}

3

var cell = (from row in grid.Rows.OfType<DataGridViewRow>()
            from cell in row.Cells.OfType<DataGridViewCell>()
            where cell.Value == somevalue
            select cell
   ).FirstOrDefault();

if (cell != null) {
   // do stuff
}

答案 1 :(得分:57)

虽然上面的许多解决方案都是正确的并且回答了你的问题,但我会退后一步并问自己“还有另一种方法可以更清楚地表示程序的语义吗?”

我倾向于写这样的代码:

var query = from row in grid.Rows
            from cell in row.Cells
            where cell.Value == myValue
            select cell;
if (query.Any())
{
  // do something useful;
}

为什么要编写任何循环?您想知道特定集合是否具有特定成员,因此请编写一个询问该问题的查询,然后检查答案。

答案 2 :(得分:35)

最令人愉快的方法是将第二个循环分解为一个函数,如下所示:

public void DoubleLoop()
{
    for(int i = 0; i < width; i++)
    {
        for(int j = 0; j < height; j++)
        {
            if(whatever[i][j]) break; // let's make this a "double" break
        }
    }
}

转到

public bool CheckWhatever(int whateverIndex)
{
    for(int j = 0; j < height; j++)
    {
        if(whatever[whateverIndex][j]) return false;
    }

    return true;
}

public void DoubleLoop()
{
    for(int i = 0; i < width; i++)
    {
        if(!CheckWhatever(i)) break;
    }
}

当然,随意使用LINQ或其他任何东西来简化它(你可以将CheckWhatever置于循环条件中。)这只是原理的详细演示。

答案 3 :(得分:23)

我只是将循环包装到一个函数中,然后让函数返回以退出我的解决方案的循环。

答案 4 :(得分:19)

        foreach (DataGridViewRow row in grid.Rows)
        {
            foreach (DataGridViewCell cell in row.Cells)
            {
                if (cell.Value == myValue)
                {
                    goto EndOfLoop;
                    //Do Something useful
                    //break out of both foreach loops.
                }
            }

        }
        EndOfLoop: ;

这将有效,但我建议使用布尔标志。

编辑: 只是在这里添加一点警告;一般认为使用goto是不好的做法,因为它们很快就会导致(几乎)无法维护的意大利面条代码。话虽这么说,它被包含在C#语言中,并且可供使用,所以显然有些人认为它具有有效的用法。知道该功能存在并非常谨慎使用。

答案 5 :(得分:14)

为了完整起见,还有错误的方法:

try
{
    foreach(DataGridViewRow row in grid.Rows)
        foreach(DataGridViewCell cell in row.Cells)
            if(cell.Value == myValue)
               throw new FoundItemException(cell);
}
catch (FoundItemException ex)
{
    //Do Something useful with ex.item
}

答案 6 :(得分:11)

C#does have a goto statement。实际上,MSDN上的示例使用它来打破双嵌套循环。

答案 7 :(得分:8)

最好的方法是不要这样做。认真;如果你想在嵌套循环中找到第一个出现的东西,然后完成查找,那么你想要做的就是不要检查每个元素,这显然只是foreach构造的作用。我建议在循环不变量中使用带有终止标志的常规for循环。

答案 8 :(得分:5)

您可以编写一个实现IEnumerator&lt; T&gt;的类。在一般情况下,然后您的枚举代码如下所示:

foreach (Foo foo in someClass.Items) {
    foreach (Bar bar in foo.Items) {
        foreach (Baz baz in bar.Items) {
            yield return baz;
        }
    }
}

// and later in client code

MyEnumerator e = new MyEnumerator(someClass);
foreach (Baz baz in e) {
    if (baz == myValue) {
        // do something useful
        break;
    }
 }

答案 9 :(得分:2)

  1. 请按照建议使用PeterAllenWebb。
  2. 将每个循环的两个包裹到一个函数中,并在想要中断时返回。
  3. 有点谷歌搜索,这是MSDN论坛上的a similar question

答案 10 :(得分:2)

  //describe how to find interesting cells
var query = from row in grid.Rows.OfType<DataGridViewRow>()
            from cell in row.Cells.OfType<DataGridViewCell>()
            where cell.Value == myValue
            select cell;
  //nab the first cell that matches, if any
DataGridViewCell theCell = query.FirstOrDefault();

  //see if we got one
if (theCell != null)
{
  //Do something with theCell
}

答案 11 :(得分:1)

把它放入一个功能&amp;找到事物后,使用return语句 在它结束时返回一个空值 - 表示找不到搜索的项目。

答案 12 :(得分:0)

您可以修改循环变量:

for (int i = 0; i < width; i++)
{
    for (int j = 0; j < height; j++)
    {
        if (NeedToBreak())
        {
            i = width;
            j = height; 
        }
    }

}

答案 13 :(得分:0)

尚未经过测试......但这样的事情可能有效

            Action dostuff =  () =>
            {

            }
        foreach (DataGridViewRow row in grid.Rows)
            foreach (DataGridViewCell cell in row.Cells)
                if (cell.Value == myValue)
                    goto A:

        A: dostuff();

答案 14 :(得分:0)

我认为您可以使用自定义例外:

set.seed(1)
df <- data.frame(matrix(sample(1:100,30),ncol=6))
#  X1 X2 X3 X4 X5 X6
#1 27 86 19 43 75 29
#2 37 97 16 88 17  1
#3 57 62 61 83 51 28
#4 89 58 34 32 10 81
#5 20  6 67 63 21 25
library(data.table)
dt <- data.table(df)


df1 <- data.frame(matrix(sample(1:100,30),ncol=6))
df1
#   X1 X2 X3 X4 X5 X6
#1  49 64 74 68 39  8
#2  60 75 58  2 88 24
#3 100 11 69 40 35 91
#4  19 67 98 61 97 48
#5  80 38 46 57  6 29
dt1 <- data.table(df1)

答案 15 :(得分:0)

这是for循环的另一个解决方案:

xcopy /y /u "artwork\*" "temp" 

答案 16 :(得分:0)

int i;
int j;
int flag = 0; // Flag used to break out of the nested loop.
char ballonColor;

if (b == NULL || b->board == NULL) { // Checks for a null board.
    flag = 0;
}
else {
    for (i = 0; i < b->rows && !flag; i++) { // Checks if the board is filled with air (no balloons).
        for (j = 0; j <= b->cols && !flag; j++) {
            if (b->board[i][j] != None) {
                flag = 1;
            }
        }
    }
}

if (flag == 0) {
    return 0;
}
else {
    for (i = 0; i < b->rows && !flag; i++) { //
        for (j = 0; j <= b->cols && !flag; j++) {
            if (b->board[i][j] != None) {
                ballonColor = b->board[i][j];
                if (i == 0) { // Top Row
                    if (j == 0) {
                        if (b->board[i + 1][j] == ballonColor || b->board[i][j + 1] == ballonColor) {
                            return 1;
                        }
                    }
                    else if (j == b->cols) {
                        if (b->board[i + 1][j] == ballonColor || b->board[i][j - 1] == ballonColor) {
                            return 1;
                        }
                    }
                    else {
                        if (b->board[i + 1][j] == ballonColor || b->board[i][j + 1] == ballonColor || b->board[i][j - 1] == ballonColor) {
                            return 1;
                        }
                    }
                }
                else if (i == (b->rows - 1)) { // Bottom Row
                    if (j == 0) {
                        if (b->board[i - 1][j] == ballonColor || b->board[i][j + 1] == ballonColor) {
                            return 1;
                        }
                    }
                    else if (j == b->cols) {
                        if (b->board[i - 1][j] == ballonColor || b->board[i][j - 1] == ballonColor) {
                            return 1;
                        }
                    }
                    else {
                        if (b->board[i - 1][j] == ballonColor || b->board[i][j + 1] == ballonColor || b->board[i][j - 1] == ballonColor) {
                            return 1;
                        }
                    }
                }
                else { // 
                    if (j == 0) {
                        if (b->board[i + 1][j] == ballonColor || b->board[i - 1][j] == ballonColor || b->board[i][j + 1] == ballonColor) {
                            return 1;
                        }
                    }
                    else if (j == b->cols) {
                        if (b->board[i + 1][j] == ballonColor || b->board[i - 1][j] == ballonColor || b->board[i][j - 1] == ballonColor) {
                            return 1;
                        }
                    }
                    else {
                        if (b->board[i + 1][j] == ballonColor || b->board[i - 1][j] == ballonColor || b->board[i][j + 1] == ballonColor || b->board[i][j - 1] == ballonColor) {
                            return 1;
                        }
                    }
                }
            }
        }
    }
}

return 0;