当前位置:  开发笔记 > 编程语言 > 正文

打破嵌套(for)循环的最佳方法是什么?

如何解决《打破嵌套(for)循环的最佳方法是什么?》经验,为你挑选了9个好方法。

在Javascript中打破嵌套循环的最佳方法是什么?

//Write the links to the page.
for (var x = 0; x < Args.length; x++)
{
   for (var Heading in Navigation.Headings)
   {
      for (var Item in Navigation.Headings[Heading])
      {
         if (Args[x] == Navigation.Headings[Heading][Item].Name)
         {
            document.write("" 
               + Navigation.Headings[Heading][Item].Name + " : ");
            break; // <---HERE, I need to break out of two loops.
         }
      }
   }
}

ephemient.. 927

就像Perl一样

loop1:
    for (var i in set1) {
loop2:
        for (var j in set2) {
loop3:
            for (var k in set3) {
                break loop2;  // breaks out of loop3 and loop2
            }
        }
    }

如EMCA-262第12.12节中的定义.[MDN Docs]

与C不同,这些标签只能用于continuebreak,因为Javascript没有goto.



1> ephemient..:

就像Perl一样

loop1:
    for (var i in set1) {
loop2:
        for (var j in set2) {
loop3:
            for (var k in set3) {
                break loop2;  // breaks out of loop3 and loop2
            }
        }
    }

如EMCA-262第12.12节中的定义.[MDN Docs]

与C不同,这些标签只能用于continuebreak,因为Javascript没有goto.


WTF为什么我没有看到这在我使用JavaScript的3年中被使用过:/ ..
MDN纯粹基于可读性理由说"避免使用标签".为什么它不"可读"?当然,因为没有人使用它们.但他们为什么不使用它们呢?...
@JérémyPouyet - 你的投票逻辑是无效的,没有根据.它完美地回答了OP的问题.问题与您对易读性的看法无关.请重新考虑您协助社区的方法.
@SeantheBean完成.这似乎是更简单的答案,并且不会滥用,因为它只能用于"继续"和"休息".
@Web_Designer我相信你的评论已经过时了.在MDN文档中没有任何地方说"避免使用标签".请考虑修改或删除您的评论.
@NielsBom你是对的:它用给定的标签打破了循环.它没有"转到"标签.你本质上是命名一个循环,说我想要摆脱这样的循环.
是"打破*标签"吗?它看起来更像是在命名一个带有n个可选嵌套循环的块,然后通过调用break {label}中止"遍历块".
我不认为在一个函数中包装会产生更多可维护的代码而不仅仅是几个标签并打破恕我直言.如果你有3或4级深度的多重嵌套循环 - 3或4个单独的意大利面功能会发生什么?
这是不好的做法.考虑使用强大的函数中的包装循环来回答.创建更易读和可维护的代码.
在我看来,包含在函数中的方式就是用这种方式标记和断开循环的可读性,因为大多数人习惯于在不同的编程语言中使用类似的方法.我现在正在编写大约3年的C#,JavaScript,Java,我发现这种方法比harley.333的答案更具可读性.
低估了一个高度赞成的不良做法(即这就像JS中的编程一样).推荐阅读JavaScript The Good Parts,并更新您的答案.
除了关于所谓的“最佳实践”的观点,如果我打开另一个程序员的代码,并且他们脱离了嵌套循环,这就是我想看到的答案。那就是我认为可读的内容:我消化某人的代码并使之有意义需要多长时间?加上许多其他人指出的那样,它是高性能的。每天都可以通过其他“更正确” /复杂的解决方案给我这个答案。

2> swilliams..:

将其包裹在一个函数中然后只是return.


for循环上的标签与GOTO完全没有任何共同点**除了它们的语法.它们只是打破外循环的问题.打破最里面的循环你没有任何问题,对吗?那你为什么要打破外环呢?
IMO,GOTO只要不破坏结构就可以了.但是每个人都自己!
我选择接受这个答案,因为它很简单,可以优雅的方式实现.我绝对讨厌GOTO,并认为它们是不好的做法(*可以打开*),Ephemient太接近了.; O)
请考虑接受其他答案.如果没有Andrew Hedges评论(谢谢顺便说一句.),我会想:啊,所以javascript没有这个功能.而且我打赌社区中的许多人可能会忽略评论,并认为同样如此.
为什么Stack Overflow没有让社区覆盖明显错误的选定答案的功能?:/

3> aleemb..:

我有点迟到了,但以下是与语言无关的方法,不使用GOTO /标签或功能包装:

for (var x = Set1.length; x > 0; x--)
{
   for (var y = Set2.length; y > 0; y--)
   {
      for (var z = Set3.length; z > 0; z--)
      {
          z = y = -1; // terminates second loop
          // z = y = x = -1; // terminate first loop
      }
   }
}

在好的方面,它自然流动,这应该取悦非GOTO人群.在缺点方面,内部循环需要在终止之前完成当前迭代,因此在某些情况下可能不适用.


@Evgeny:虽然一些JavaScript样式指南要求打开括号在同一行上,但是将它放在新行上是不正确的,并且没有解释器模糊地插入分号的危险.ASI的行为定义明确,不适用于此处.
只要确保评论这种方法的地狱.现在发生的事情并不是很明显.
左括号不应该在新行上,因为js实现可能会在前一行的末尾插入一个冒号.

4> zord..:

我意识到这是一个非常古老的话题,但由于我的标准方法还没有到来,我想我会把它发布给未来的googlers.

var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}


不,它从两个循环中退出.这是演示[小提琴](http://jsfiddle.net/zmkfY/).无论你设定什么条件,它都会在它满足之后退出.
优化是增加休息时间; 设置abort = true后; 并从最终循环中删除!中止条件检查.

5> harley.333..:
var str = "";
for (var x = 0; x < 3; x++) {
    (function() {  // here's an anonymous function
        for (var y = 0; y < 3; y++) {
            for (var z = 0; z < 3; z++) {
                // you have access to 'x' because of closures
                str += "x=" + x + "  y=" + y + "  z=" + z + "
"; if (x == z && z == 2) { return; } } } })(); // here, you execute your anonymous function }

怎么样?:)


如果循环很大,这会增加显着的运行时成本 - 必须通过Javascript解释器/编译器创建函数的新执行上下文(并且在某些时候由GC释放)(或者,这些天的"compreter",两者的混合)每一次.
我认为这就是swilliams所得到的
这实际上非常危险,因为一些奇怪的东西可能会发生,你可能没想到.特别是,由于使用var`x`创建的闭包,如果循环中的任何逻辑在稍后的时间点引用x(例如,它定义了一个保存并稍后执行的内部匿名函数),x的值将为无论它在循环的*end*处是什么,而不是函数在其中定义的索引.(续)
同样,我认为可读性是完全废话。这比标签更模糊。标签仅被视为“不可读”,因为没有人使用过它们。

6> 小智..:

非常简单

var a=[1,2,3];
var b=[4,5,6];
var breakCheck1=false;

for (var i in a){
    for (var j in b){
        breakCheck1=true;
        break;
    }
    if (breakCheck1) {break;}
}



7> Drakes..:

如何完全不使用中断,没有中止标志,也没有额外的条件检查.这个版本只是Number.MAX_VALUE在满足条件时抛出循环变量(使它们)并强制所有循环优雅地终止.

// No breaks needed
for (var i = 0; i < 10; i++) {
  for (var j = 0; j < 10; j++) {
    if (condition) {
      console.log("condition met");
      i = j = Number.MAX_VALUE; // Blast the loop variables
    }
  }
}

对于递减类型的嵌套循环,有一个类似的答案,但是这适用于递增类型的嵌套循环,而不需要考虑简单循环的每个循环的终止值.

另一个例子:

// No breaks needed
for (var i = 0; i < 89; i++) {
  for (var j = 0; j < 1002; j++) {
    for (var k = 0; k < 16; k++) {
      for (var l = 0; l < 2382; l++) {
        if (condition) {
          console.log("condition met");
          i = j = k = l = Number.MAX_VALUE; // Blast the loop variables
        }
      }
    }
  }
}



8> Dan Bray..:

以下是打破JavaScript中的嵌套循环的五种方法:

1)将父循环设置为结尾

for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
        {
            i = 5;
            break;
        }
    }
}

2)使用标签

exit_loops:
for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
            break exit_loops;
    }
}

3)使用变量

var exit_loops = false;
for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
        {
            exit_loops = true;
            break;
        }
    }
    if (exit_loops)
        break;
}

4)使用自我执行功能

(function()
{
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
        {
             if (j === 2)
                 return;
        }
    }
})();

5)使用常规功能

function nested_loops()
{
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
        {
             if (j === 2)
                 return;
        }
    }
}
nested_loops();



9> user889030..:

如何将循环推到最终限制

    for(var a=0; a

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有