打破 JavaScript 嵌套循环的最佳方法是什么?

IT技术 javascript loops nested-loops break
2021-01-23 11:11:28

在 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("<a href=\"" 
               + Navigation.Headings[Heading][Item].URL + "\">" 
               + Navigation.Headings[Heading][Item].Name + "</a> : ");
            break; // <---HERE, I need to break out of two loops.
         }
      }
   }
}
6个回答

就像 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 文档]

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

@JérémyPouyet - 你反对投票的逻辑是愚蠢和毫无根据的。它完美地回答了 OP 的问题。该问题与您对易读性的看法无关。请重新考虑您帮助社区的方法。
2021-03-22 11:11:28
@Web_Designer 我相信你的评论已经过时了。MDN 文档中没有任何地方说“避免使用标签”。请考虑修改或删除您的评论。
2021-03-27 11:11:28
MDN 说“避免使用标签”纯粹是出于可读性的考虑。为什么它不“可读”?因为当然没有人使用它们。但是他们为什么不使用它们呢?...
2021-03-28 11:11:28
@SeantheBean 完成。这似乎是更直接的答案并且不会被滥用,因为它仅适用于continuebreak
2021-04-05 11:11:28
WTF 为什么我在 3 年的时间里没有看到在 JavaScript 中使用它:/..
2021-04-08 11:11:28

将其封装在一个函数中,然后将return.

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

我参加聚会有点晚了,但以下是一种与语言无关的方法,它不使用 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 人群。不利的一面是,内循环需要在终止之前完成当前迭代,因此它可能不适用于某些场景。

我可能遗漏了一些东西,但是为了解决内部循环必须完成迭代的问题,你可以在设置 z 和 y 之后立即放入 abreakcontinue立即吗?我确实喜欢使用for循环的条件来踢出的想法以自己的方式优雅。
2021-03-13 11:11:28
只要确保评论这种方法的地狱。目前还不清楚这里发生了什么。
2021-03-25 11:11:28
左大括号不应该在新行上,因为 js 实现可能会在前一行的末尾插入一个冒号。
2021-03-27 11:11:28
@Evgeny:虽然一些 JavaScript 风格指南要求左大括号放在同一行,但将它放在新行上并没有错,并且解释器不存在歧义插入分号的危险。ASI 的行为定义明确,不适用于此处。
2021-04-04 11:11:28
漂亮而简单的答案。这应该被视为答案,因为它不会给 CPU 密集型循环带来压力(这是使用函数的问题),或者它不使用标签,标签通常不可读或不应该像某些人所说的那样使用。:)
2021-04-06 11:11:28

我意识到这是一个非常古老的话题,但由于我的标准方法还没有出现,我想我将它发布给未来的谷歌员工。

var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}
我喜欢这个,但我认为在一般意义上你会做很多不必要的处理——也就是说,对于每个迭代器评估abort和表达式的每次迭代在简单的场景中可能没问题,但对于具有无数次迭代的巨大循环来说可能是一个问题
2021-03-12 11:11:28
+1 为一种新颖的方法!但是,这对循环没有帮助for(var a in b){...}for(var a of b){...}样式。
2021-03-14 11:11:28
优化是增加一个休息时间;设置 abort = true 后;并从最终循环中删除 !abort 条件检查。
2021-03-31 11:11:28
不,它从两个循环中退出。这是演示小提琴无论你设置什么条件,它都会在满足后退出。
2021-04-04 11:11:28
如果condition计算结果为true在嵌套循环的第一次迭代,你仍然可以通过10次迭代的其余部分运行,检查abort每一时间值。这不是 10 次迭代的性能问题,但它会出现,例如,10,000。
2021-04-06 11:11:28

非常简单:

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;
}
我同意这实际上是最好的,第一个函数不能扩展,如果也不能扩展,则将所有 for 循环包装起来,即使其难以阅读和调试......这个很棒。您可以只声明 vars loop1、loop2、loop3,并在最后添加小语句。另外要打破多个循环,你需要做类似的事情loop1=loop2=false;
2021-03-28 11:11:28
我已经使用了这种安排并且它可以工作,并且没有用无用的功能使其复杂化。我只是在搜索了一些东西之后才到达这里,看看 js 是否break 2;像 php 一样。
2021-04-09 11:11:28