web-dev-qa-db-ja.com

ネストされたjQuery.each()-続行/中断

次のコードを検討してください。

    var sentences = [
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
        'Vivamus aliquet nisl quis velit ornare tempor.',
        'Cras sit amet neque ante, eu ultrices est.',
        'Integer id lectus id nunc venenatis gravida nec eget dolor.',
        'Suspendisse imperdiet turpis ut justo ultricies a aliquet tortor ultrices.'
    ];

    var words = ['ipsum', 'amet', 'elit'];

    $(sentences).each(function() {
        var s = this;
        alert(s);
        $(words).each(function(i) {
            if (s.indexOf(this) > -1)
            {
                alert('found ' + this);
                return false;
            }
        });
    });

興味深い部分は、ネストされたjQuery.each()ループです。 ドキュメント に従って、falseを返すとループから抜け出し(ループの実行を中止します-通常のJavaScriptのbreakステートメントと同様)、false以外を返すと現在の反復が停止し、次の反復(通常のJavaScriptのcontinueステートメントに類似)。

JQuery.each()を単独で中断または続行できますが、ネストされたjQuery.eachを使用すると、子ループ内から親ループから抜け出すことが難しいことがわかりました。ブール値を使用し、すべての子の反復で更新できましたが、もっと簡単な方法があるかどうか疑問に思っていました。

jsFiddleの例 を設定しました。これをいじりたい場合。 [テスト]ボタンをクリックして、上記の例を実行します。

TLDR:jQueryのコンテキスト内で、ラベル付きのcontinueまたはbreakに似たものはありますか?

41
Ryan Kinal

これを行う必要がありますwithout jQuery、「きれい」ではないかもしれませんが、以下のようになり、正確にやりたいことが簡単になります。

var sentences = [
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
    'Vivamus aliquet nisl quis velit ornare tempor.',
    'Cras sit amet neque ante, eu ultrices est.',
    'Integer id lectus id nunc venenatis gravida nec eget dolor.',
    'Suspendisse imperdiet turpis ut justo ultricies a aliquet tortor ultrices.'
];

var words = ['ipsum', 'amet', 'elit'];

for(var s=0; s<sentences.length; s++) {
    alert(sentences[s]);
    for(var w=0; w<words.length; w++) {
        if(sentences[s].indexOf(words[w]) > -1) {
            alert('found ' + words[w]);
            return;
        }
    }
}

ここで試してみることができます 。これがexactの振る舞いであるかどうかはわかりませんが、double .each() そして、この場合はいつでもreturnまたはbreakできます。

22
Nick Craver

ここには多くの答えがあります。そしてそれは古いですが、これはグーグル経由でここに来る人のためのものです。 jQueryの各関数

return false;breakのようなものです。

ただ

return;continueのようなものです

これらは、breakおよびcontinueの動作をエミュレートします。

92
Thihara

JQueryのドキュメントに記載されているとおり http://api.jquery.com/jQuery.each/

return true in jQuery.eachcontinueと同じです

return falsebreakと同じです

12
Serj Sagan

これを行うための明確な方法はなく、上記の@Nickのように、これを制御できるので、従来のループの方法を使用する方が簡単かもしれません。しかし、あなたが得たものに固執したいなら、あなたはこれを扱うことができる1つの方法です。私はこれのためにいくらかの熱を得ると確信しています。しかし...

Ifステートメントなしでやりたいことができる1つの方法は、エラーを発生させ、ループをtry/catchブロックでラップすることです。

try{
$(sentences).each(function() {
    var s = this;
    alert(s);
    $(words).each(function(i) {
        if (s.indexOf(this) > -1)
        {
            alert('found ' + this);
            throw "Exit Error";
        }
    });
});
}
catch (e)
{
    alert(e)
}

OK、スラッシングを始めましょう。

8
spinon

ここでの問題は、.eachコールバック内からfalseを返すことができる一方で、.each関数自体がjQueryオブジェクトを返すことです。そのため、ループの反復を停止するには、両方のレベルでfalseを返す必要があります。また、内部の.eachが一致したかどうかを知る方法がないため、更新されるクロージャを使用して共有変数を使用する必要があります。

wordsの各内部反復は、同じnotFound変数を参照するため、一致が見つかったときにそれを更新し、それを返すだけです。外側のクロージャーには既にそれへの参照があるので、必要なときにbreakアウトできます。

$(sentences).each(function() {
    var s = this;
    var notFound = true;

    $(words).each(function() {
        return (notFound = (s.indexOf(this) == -1));
    });

    return notFound;
});

ここの例 を試すことができます。

7
Anurag

これには「ブレイクアウト」パターンを使用しました。

$(sentences).each(function() {
    var breakout;
    var s = this;
    alert(s);
    $(words).each(function(i) {
        if (s.indexOf(this) > -1)
        {
            alert('found ' + this);
            return breakout = false;
        }
    });
    return breakout;
});

これは、任意のネストの深さでうまく機能します。 breakoutは単純なフラグです。 undefinedに設定しない限り、falseのままになります(上記のreturnステートメントで行うように)。あなたがしなければならないのは:

  1. 一番外側のクロージャーで宣言してください:var breakout;
  2. return falseステートメントに追加:return breakout = false
  3. 外側のクロージャーでブレークアウトを返します。

あまりにもエレガントではありませんか? ...とにかく私のために働く。

5
joneit

APIドキュメントで確認 http://api.jquery.com/jQuery.each/ say:

コールバック関数がfalseを返すようにすることで、特定の反復で$ .each()ループを中断できます。 false以外を返すことは、forループのcontinueステートメントと同じです。すぐに次の反復にスキップします。

これは私の例です http://jsfiddle.net/r6jqP/

(function($){
    $('#go').on('click',function(){
        var i=0,
            all=0;
        $('li').each(function(){
             all++;
             if($('#mytext').val()=='continue')return true;
             i++;
             if($('#mytext').val()==$(this).html()){
                 return false;
             }
        });
        alert('Iterazione : '+i+' to '+all);
    });
}(jQuery));
3

trueを返す動作しない

falseを返す動作中

found = false;
query = "foo";

$('.items').each(function()
{
  if($(this).text() == query)
  {
    found = true;
    return false;
  }
});
3
misima

残念だけど違う。ここでの問題は、関数内で反復が発生するため、通常のループとは異なることです。関数から抜け出すことができる唯一の方法は、返すか、例外をスローすることです。そのため、ブールフラグを使用することが、外側の「ループ」から「ブレイク」する唯一の合理的な方法のようです。

3
casablanca

ラベル付きブレーク

outerloop:
$(sentences).each(function() 
{
    $(words).each(function(i) 
    {
        break; /* breaks inner loop */
    } 
    $(words).each(function(i)  
    {
        break outerloop; /* breaks outer loop */
    }
}
2
capdragon