我一次又一次遇到的是嵌套循环,搜索一些2D数组以找到一个元素(通常是一些对象),然后必须对其进行操作.所以当然,一旦你找到那个对象,就应该打破这两个循环,这样你就不必不必要地继续搜索你已经找到的东西(特别是在可以遍历指数巨大数组的嵌套循环中).
以下代码是我目前的首选方式:
Obj O = null; bool KeepLooping = true; for (int j = 0; j < height && KeepLooping; j++) { for (int i = 0; i < width; i++) { if (ObjArray[i,j] != null && ObjArray[i,j].property == search_value) { O = ObjArray[i,j]; // you found it,Now remember it KeepLooping = false; // clear the flag so the outer loop will break too break; } } }
感谢Erik Funkenbusch,如果我们这样做,它会变得更加优雅:
Obj O = null; for (int j = 0; j < height && O == null; j++) // much,much better idea to check O for null in the outer loop { for (int i = 0; i < width; i++) { if (ObjArray[i,Now remember it break; } } }
不再需要那个讨厌的额外布尔值!
然而,寻求替代或更好的解决方案仍在继续.这些年来,我尝试了很多其他的方法,但发现它们并不是因为某种原因而变得那么好:
>将j(外循环迭代器)设置为高于高度的值,这将触发它自动中断.不理想,因为有时你想记住你发现它的i和j值.
>在2D阵列上使用foreach.不太理想,因为foreach不会让你操纵集合(删除或添加它,这通常是我搜索对象的原因).
>只需将2个循环放在一个除了查找并返回O之外什么都不做的函数中.返回有效地打破了两个循环.很多时候这没关系,但并非总是如此.我这样做是为了非常通用的搜索,但也有很多“群组搜索”,我想集体化遍历.在这些情况下,我找到2个或更多的对象(有时在同一个2D数组中),记住它们,然后才会中断两个循环.
>使用转到? (哇,这可能是goto的唯一合法使用吗?它比KeepLooping标志更具可读性,特别是如果我们有3个或更多循环.)不理想,因为同事会尖叫血腥谋杀.在C#中,goto之后会有正确的垃圾清理吗?
>抛出自定义异常? idk,我从未尝试过,但它看起来不像我目前喜欢的方式.
>一旦找到了正确的对象,在内部循环中进行所有对象操作,然后返回;这可能会很快变得凌乱.有时,对象操作涉及自己的循环.
由于User_PWY,还有一个非常聪明的第7种方式:
int size = width*height; // save this so you dont have to keep remultiplying it every iteration for (int i = 0; i < size; i++) { int x = i % width; // ingenIoUs method here int y = i / width; // ingenIoUs method here O = ObjArray[x,y]; if (O != null) break; // woohoo! }
这有效地将2D阵列压缩成一个用于迭代的循环.然而,一些批评指出,与i或j相比,mod和除法运算符相当缓慢,因此它可能会更慢(请记住我们正在处理谁知道什么大小的2D数组).就像我评论的那样,应该有一种方法可以在一次操作中得到除法和余数,因为我非常确定x86汇编代码具有DIV操作码,它将商和余数存储在单独的寄存器中,所有这些都在一个DIV指令中.但是如何在C#中使用它,idk.
如果C#允许你命名循环(如L1和L2)然后执行类似L1.break()的操作,那将是很好的.无论你在哪个循环中.唉……用这种语言做不到. (有没有一些秘密的方法可以使用宏来做到这一点?)是否有一个C#6.0实现了这个功能?
编辑:在我看来,我判断他们的优雅和速度的解决方案.请记住,我们正在处理嵌套循环,这可能会成倍增长.额外的操作或比较可能会有所不同.
好吧,好吧,告诉我你喜欢的方式,特别是如果这里没有列出的话.
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。