作为一个简单的例子,我可以说我有以下网格,我正在寻找特定的单元格值。找到后我不再需要处理循环。
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#中实现此目的的最简洁方法是什么?我知道我可以设置一个布尔标志,并在外部循环中检查它以突破那个,但它看起来太冗长了。
谢谢,
答案 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)
有点谷歌搜索,这是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;