640 Stimmen

Was ist der beste Weg, um aus verschachtelten Schleifen in JavaScript zu brechen?

Was ist der beste Weg, um aus verschachtelten Schleifen in Javascript zu brechen?

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

0 Stimmen

Hier ist ein gutes Beispiel für den Ausbruch aus Schleifen und Codeblöcken: marcin-chwedczuk.github.io/

54voto

Dan Bray Punkte 6353

Hier sind fünf Möglichkeiten, um aus verschachtelten Schleifen in JavaScript auszubrechen:

1) Elternteil(e)-Schleife an das Ende setzen

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

2) Etikett verwenden

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

3) Variable verwenden

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) Selbstausführende Funktion verwenden

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

5) Regelmäßige Funktion verwenden

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

4 Stimmen

@Wyck Ich kann nicht genug zustimmen! Es ist eine Schande, javascript nicht einfach eine Syntax haben break 2; wie wir sie in PHP haben. Keine Schleifenbezeichnungen, keine Funktionen, keine if-else-Prüfungen, kein Temperieren mit / Sprengen von Schleifenvariablen - nur saubere Syntax!

4 Stimmen

Beispiel 4 ist raffiniert

0 Stimmen

@JayDadhania Tut mir leid, aber Ihre "saubere" und "einfache" Syntax führt zu Fehlern in unserer Software. Explizit ist besser als implizit. Ich möchte meine Etiketten selbst benennen.

44voto

harley.333 Punkte 3636
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
}

Wie war das? :)

2 Stimmen

Ich dachte mir, dass Swilliams genau darauf hinauswollte.

0 Stimmen

Vielen Dank, dass Sie das so deutlich formuliert haben. Ich vergesse immer, dass ich jedes beliebige Stück Code in eine anonyme Funktion verpacken und diese aufrufen kann.

21 Stimmen

Dies führt zu erheblichen Laufzeitkosten, wenn die Schleife groß ist - ein neuer Ausführungskontext für die Funktion muss vom Javascript-Interpreter/Compiler (oder "Compreter" heutzutage, eine Mischung aus beidem) JEDES MAL erstellt (und irgendwann von GC freigegeben) werden.

17voto

Drakes Punkte 21987

Wie wäre es, überhaupt keine Unterbrechungen, keine Abbruchkennzeichen und keine zusätzlichen Bedingungsprüfungen zu verwenden? Diese Version lässt die Schleifenvariablen einfach explodieren (macht sie Number.MAX_VALUE ), wenn die Bedingung erfüllt ist, und zwingt alle Schleifen zu einer eleganten Beendigung.

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

Es gab eine ähnliche Antwort für verschachtelte Schleifen des dekrementierenden Typs, aber dies funktioniert auch für verschachtelte Schleifen des inkrementierenden Typs, ohne dass der Endwert jeder Schleife für einfache Schleifen berücksichtigt werden muss.

Ein weiteres Beispiel:

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

3voto

Nick Perkins Punkte 7583

Wenn Sie Coffeescript verwenden, gibt es ein praktisches "do"-Schlüsselwort, das es einfacher macht, eine anonyme Funktion zu definieren und sofort auszuführen:

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

...so dass Sie einfach "return" verwenden können, um aus den Schleifen herauszukommen.

0 Stimmen

Das ist nicht das Gleiche. Mein ursprüngliches Beispiel hat drei for Schleifen, nicht zwei.

2voto

Zachary Ryan Smith Punkte 2491

Ich dachte, ich zeige einen Ansatz der funktionalen Programmierung. Sie können aus verschachtelten Array.prototype.some() und/oder Array.prototype.every() Funktionen ausbrechen, wie in meinen Lösungen. Ein zusätzlicher Vorteil dieses Ansatzes ist, dass Object.keys() zählt nur die eigenen aufzählbaren Eigenschaften eines Objekts auf, während "eine for-in-Schleife zählt auch die Eigenschaften in der Prototypenkette auf" .

Kommt der Lösung des Auftraggebers sehr nahe:

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

Lösung, die die Iteration über die Überschriften/Elemente reduziert:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X