La meilleure façon de rompre avec les boucles imbriquées en Javascript?

Quelle est la meilleure façon de rompre avec les boucles imbriquées en 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.
         }
      }
   }
}
316
demandé sur webeno 2008-10-08 18:47:25
la source

13 ответов

comme 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
            }
        }
    }

tel que défini à L'article 12.12 de L'EMCA-262. [MDN Docs]

contrairement à C, Ces étiquettes ne peuvent être utilisées que pour continue et break , comme Javascript n'a pas goto .

750
répondu ephemient 2018-01-05 00:19:18
la source

enveloppez ça dans une fonction et ensuite juste return .

128
répondu swilliams 2013-12-05 11:41:22
la source

je suis un peu en retard pour le parti, mais ce qui suit est une approche agnostique qui n'utilise pas de goto/étiquettes ou d'emballage de fonction:

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
      }
   }
}

à l'envers il coule naturellement ce qui devrait plaire à la foule non-GOTO. Par contre, la boucle interne doit terminer l'itération en cours avant de s'arrêter, de sorte qu'elle pourrait ne pas être applicable dans certains scénarios.

67
répondu aleemb 2009-04-08 02:11:59
la source

je me rends compte que c'est un sujet très ancien, mais puisque mon approche standard n'est pas encore là, j'ai pensé l'afficher pour les futurs googleurs.

var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}
59
répondu zord 2013-11-19 00:08:16
la source
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
}

comment ça? :)

35
répondu harley.333 2008-10-08 23:42:23
la source

tout à fait simple

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;}
}
32
répondu 2009-07-16 19:22:31
la source

pourquoi ne pas utiliser Pas de pauses, pas de signal d'abandon, et pas de vérifications supplémentaires. Cette version envoie juste les variables de boucle (les rend Number.MAX_VALUE ) quand la condition est remplie et force toutes les boucles à se terminer élégamment.

// 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
    }
  }
}

il y avait une réponse semblable pour les boucles imbriquées de type Décrémentation, mais cela fonctionne pour les boucles imbriquées de type incrémentation sans avoir besoin de considérer la valeur de terminaison de chaque boucle pour les boucles simples.

autre exemple:

// 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
        }
      }
    }
  }
}
12
répondu Drakes 2015-05-11 04:33:57
la source

Que Diriez-vous de pousser les boucles à leurs limites d'extrémité

    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;
            }
         }
       }
     }
4
répondu user889030 2017-09-26 13:58:40
la source

si vous utilisez Coffeescript, il existe un mot-clé pratique "do" qui facilite la définition et l'exécution immédiate d'une fonction anonyme:

do ->
  for a in first_loop
    for b in second_loop
      if condition(...)
        return

... donc vous pouvez simplement utiliser" return " pour sortir des boucles.

3
répondu Nick Perkins 2015-08-10 23:46:35
la source

j'ai pensé montrer une approche de programmation fonctionnelle. Vous pouvez vous évader du réseau imbriqué.prototype.certains() et/ou un Tableau.prototype.toutes les fonctions de (), comme dans mes solutions. Un autre avantage de cette approche est que Object.keys() n'énumère que les propriétés énumérables d'un objet, alors que "une boucle for-in énumère aussi les propriétés dans la chaîne prototype" .

proche de la solution 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;
    }

Solution qui réduit les itérations sur les rubriques/ éléments:

    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;
            }
        });
    });
2
répondu Zachary Ryan Smith 2015-08-24 21:36:27
la source
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;
};
-3
répondu Triqui 2012-07-13 02:16:16
la source

la meilleure façon est -

1) Trier le tableau qui sont utilisés dans la première et la deuxième boucle.

2) si l'article correspond alors briser la boucle interne et tenir la valeur de l'indice.

3) lors du démarrage de la prochaine itération, démarrez la boucle interne avec l'indice hold.

-4
répondu Deepak Karma 2016-06-23 20:59:58
la source

je sais que cela a été demandé il y a 8 ans mais dans ES6 nous avons obtenu le pour...de boucle qui permet l'utilisation de pause standard fonctionnalité:

for (let item of items) {
  if (item.id === id) {
    //do something cool
    break;
  }
}
-5
répondu vladexologija 2017-03-27 17:02:48
la source

Autres questions sur javascript loops break nested-loops