在Javascript中嵌套循环的最佳方法是什么?
什么是最好的方式来打破在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. } } } }
就像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不同,这些标签只能用于continue
和break
,因为Javascript没有goto
(没有像这样的黑客)。
把它放在一个函数中,然后return
。
我晚了一点晚,但以下是不使用GOTO /标签或function包装的语言不可知的方法:
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 } } }
它的优点是自然stream动,这应该让非GOTO人群满意。 不利的一面是,内部循环需要在终止之前完成当前迭代,所以在某些情况下可能不适用。
我意识到这是一个非常古老的话题,但是由于我的标准方法还没有出现,所以我想我会把它发布给未来的Google。
var a, b, abort = false; for (a = 0; a < 10 && !abort; a++) { for (b = 0; b < 10 && !abort; b++) { if (condition) { doSomeThing(); abort = true; } } }
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 + "<br />"; if (x == z && z == 2) { return; } } } })(); // here, you execute your anonymous function }
怎么样? 🙂
非常简单
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;} }
如何使用没有rest,没有中止标志,没有额外的条件检查。 当条件满足时,这个版本只会发送循环variables(使它们为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 } } }
对于递减types的嵌套循环,有一个相似的答案,但是这适用于增量型嵌套循环,而不需要考虑简单循环的每个循环的终止值。
另一个例子:
// 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 } } } } }
如果您使用Coffeescript,则有一个方便的“do”关键字,可以更容易地定义并立即执行一个匿名函数:
do -> for a in first_loop for b in second_loop if condition(...) return
…所以你可以简单地使用“返回”来摆脱循环。
我想我会展示一个函数式编程的方法。 你可以打破嵌套的Array.prototype.some()和/或Array.prototype.every()函数,就像我的解决scheme。 这种方法的一个额外的好处是Object.keys()
只枚举一个对象自己的枚举属性,而“一个for-in循环枚举原型链中的属性” 。
接近OP的解决scheme:
Args.forEach(function (arg) { // This guard is not necessary, // since writing an empty string to document would not change it. if (!getAnchorTag(arg)) return; document.write(getAnchorTag(arg)); }); function getAnchorTag (name) { var res = ''; Object.keys(Navigation.Headings).some(function (Heading) { return Object.keys(Navigation.Headings[Heading]).some(function (Item) { if (name == Navigation.Headings[Heading][Item].Name) { res = ("<a href=\"" + Navigation.Headings[Heading][Item].URL + "\">" + Navigation.Headings[Heading][Item].Name + "</a> : "); return true; } }); }); return res; }
减less对标题/项目迭代的解决scheme:
var remainingArgs = Args.slice(0); Object.keys(Navigation.Headings).some(function (Heading) { return Object.keys(Navigation.Headings[Heading]).some(function (Item) { var i = remainingArgs.indexOf(Navigation.Headings[Heading][Item].Name); if (i === -1) return; document.write("<a href=\"" + Navigation.Headings[Heading][Item].URL + "\">" + Navigation.Headings[Heading][Item].Name + "</a> : "); remainingArgs.splice(i, 1); if (remainingArgs.length === 0) return true; } }); });
我知道这是8年前问的,但是在ES6中,我们得到了可以使用标准中断function的for …循环:
for (let item of items) { if (item.id === id) { //do something cool break; } }
如何推循环到他们的最终限制
for(var a=0; a<data_a.length; a++){ for(var b=0; b<data_b.length; b++){ for(var c=0; c<data_c.length; c++){ for(var d=0; d<data_d.length; d++){ a = data_a.length; b = data_b.length; c = data_b.length; d = data_d.length; } } } }
XXX.Validation = function() { var ok = false; loop: do { for (...) { while (...) { if (...) { break loop; // Exist the outermost do-while loop } if (...) { continue; // skips current iteration in the while loop } } } if (...) { break loop; } if (...) { break loop; } if (...) { break loop; } if (...) { break loop; } ok = true; break; } while(true); CleanupAndCallbackBeforeReturning(ok); return ok; };
最好的办法是 –
1)对在第一和第二循环中使用的两个数组进行sorting。
2)如果项目匹配,则打破内部循环并保持索引值。
3)当下一次迭代开始时,开始保持索引值的内部循环。