在Javascript中嵌套循环的最佳方法是什么?
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 Docs]
总结,最多的功能,然后就return
。
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
}
那是怎么回事? :)
我想这是什么swilliams得到 – 2008-10-08 20:13:55
谢谢你明确这样拼写出来。我总是忘记我可以将任意一段代码封装在一个匿名函数中,然后调用它。 – Emily 2011-01-04 16:31:16
如果循环很大,这会增加很大的运行时间成本 - 必须通过Javascript解释器/编译器(或者“compreter”)创建一个新的函数执行上下文(并且在某些时候由GC释放) ) 每一次。 – 2011-10-18 12:29:04
我有点迟到了,但下面是一个语言无关的方法不使用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人群。不利的一面是,内部循环需要在终止之前完成当前迭代,因此在某些情况下可能不适用。
很简单
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;}
}
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;
};
我意识到这是一个真正的老话题,但因为我的标准的方法还没有实现,我想我将它张贴在未来的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;
}
}
}
如何使用没有休息可言,没有放弃的标志,并没有多余的条件检查。当条件满足时,这个版本只会发送循环变量(使它们为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
}
}
}
}
}
如果使用CoffeeScript中,有一个方便的“做”的关键字,可以更容易定义和立即执行的匿名函数:
do ->
for a in first_loop
for b in second_loop
if condition(...)
return
...所以你可以简单地使用“返回”来摆脱循环。
我想我会展示一个函数式编程方法。你可以跳出嵌套的Array.prototype.some()和/或Array.prototype.every()函数,就像我的解决方案一样。这种方法的另一个好处是Object.keys()
只枚举一个对象自己的枚举属性,而"a for-in loop enumerates properties in the prototype chain as well"。
关闭到OP的溶液:
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;
}
解决方案,降低遍历标题/项目:
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;
}
});
});
最好的办法是 -
1)分类的两个阵列,其被用于在第一和第二回路中。
2)如果项目匹配,则打破内部循环并保持索引值。
3)当开始下一次迭代时启动内部循环并保持索引值。
我知道这是8年前提出,但在ES6我们得到了for...of循环从而能够使用的标准突破功能:
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;
}
}
}
}
有趣!我没有意识到你可以打破标签。 – 2008-10-08 15:09:56
它是“打破”*标签“吗?它看起来更像是你用n个可选嵌套循环命名一个块,然后通过调用break {label}来中止“遍历块”。 – 2011-12-08 15:17:04
@NielsBom你是对的:它打破了给定标签的循环。它不会“转到”标签。你本质上是命名一个循环,并说我想跳出一个循环。 – devios1 2012-05-31 21:50:01