web-dev-qa-db-ja.com

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.
         }
      }
   }
}
364
Gary Willoughby

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]

Cとは異なり、Javascriptにはcontinueがないため、これらのラベルは break および goto にしか使用できません。

864
ephemient

それを関数でラップしてから、returnを付けます。

144
swilliams

私はパーティーに少し遅れていますが、以下は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群衆を喜ばせるはずです。欠点として、内部ループは終了する前に現在の反復を完了する必要があるため、シナリオによっては適用できない場合があります。

75
aleemb

これは非常に古いトピックであることを私は認識していますが、私の標準的なアプローチはまだここにはないので、私は将来のグーグラーのためにそれを投稿することを考えました。

var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}
66
zord
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
}

どのようだ? :)

39
harley.333

とても簡単

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
Paul Di Biase

まったく休憩を使用しない、アボートフラグを使用しない、および追加の条件チェックを使用しないでください。このバージョンでは、条件が満たされたときにループ変数が破壊され(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
        }
      }
    }
  }
}
14
Drakes

JavaScriptで入れ子になったループから抜け出すための5つの方法は次のとおりです。

1)親ループを最後に設定します

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

2)ラベルを使用

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

)変数を使う

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)自己実行機能を使う

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

5)通常の機能を使う

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

ループを限界に近づけることはどうですか

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

あなたがCoffeescriptを使用する場合、無名関数の定義と即時実行をより簡単にする便利な "do"キーワードがあります。

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

...だからあなたは単にループから抜け出すために "return"を使うことができます。

3
Nick Perkins

私は関数型プログラミングのアプローチを見せたいと思った。私の解決策のように、入れ子になったArray.prototype.some()やArray.prototype.every()関数から抜け出すことができます。このアプローチの追加の利点は、Object.keys()はオブジェクト自身の列挙可能なプロパティのみを列挙するのに対し、 "for-inループはプロトタイプチェーンのプロパティも列挙する" です。

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

すでにswilliamsで言及されていますが、以下の例で(Javascript):

// Function wrapping inner for loop
function CriteriaMatch(record, criteria) {
  for (var k in criteria) {
    if (!(k in record))
      return false;

    if (record[k] != criteria[k])
      return false;
  }

  return true;
}

// Outer for loop implementing continue if inner for loop returns false
var result = [];

for (var i = 0; i < _table.length; i++) {
  var r = _table[i];

  if (!CriteriaMatch(r[i], criteria))
    continue;

  result.add(r);
}
1
Original Poster

うーん、10歳のパーティーにこんにちは?

なんらかの条件をつけてみませんか?

var condition = true
for (var i = 0 ; i < Args.length && condition ; i++) {
    for (var j = 0 ; j < Args[i].length && condition ; j++) {
        if (Args[i].obj[j] == "[condition]") {
            condition = false
        }
    }
}

このようにあなたが望むときに停止します

私の場合、TypeScriptを使用して、配列を通過して条件が満たされたときに停止するsome()を使用できます。したがって、私のコードは次のようになります。

Args.some((listObj) => {
    return listObj.some((obj) => {
        return !(obj == "[condition]")
    })
})

このように、条件が満たされた直後にループが停止しました

注意:このコードはTypeScriptで実行されます

0
Azutanguy