2024年3月11日月曜日

JavaScriptでの奇妙な問題 - forEachがループを抜ける - returnがなぜ効かないのか!?

この前、私がLeetCodeの問題練習をしていて、JavaScriptに関する問題に遭遇しました。忘れないように、メモしておきました。



事の経緯は以下の通りです(一部のコードを抜粋しました)

配列に対してforEachループを行う部分があります(Object.valuesは配列を返します)
    //2.order by values
    var k = Object.values(dict);
    k.sort();
    k = k.reverse();
    
    //3.find result
    var res = 0;
    k.forEach(function(s){
        if (s>mid)
        {                
            return res == 0 ? 1 : res+1;
        }
        else if (s<mid)
        {
            mid -= s;
            res +=1;
        }
        else    //s == mid
        {
            return res+1;
        }
    });
    return res;

確かに、そのロジックには問題がないはずなのに、なぜ常に提出が失敗するのか不思議です。

確認したところ、どうやら23行目までしか実行されず、その後の処理が行われていないようです。

何が起こっているのでしょうか?上記のif else文にはreturnが必要ですが、なぜ効果がないのでしょうか?

確かに不思議ですね。それでは、簡単なプログラムを使って試してみましょう。



function test() {
    arr = ['apple','pineapple','orange','lemon'];

    let result = '';

    arr.forEach(function(s){
        if(s=='apple')
        {
            result = 'りんご';
        }
        else if(s=='orange')
        {
            result = 'オレンジ';
        }
    });

    return '桜';
}
k = test();
ああ…私たちは【桜】を得た…明らかにりんごであるべきなのに…

それでは、次のJavaScriptの技術ドキュメントを見てみましょう。以下のようなものを見つけました。



ええっ!?異常を投げないと中止できないの?普段使っているC#のforeachとはまったく違うんですね。

だから最初の問題は基本的なforループを使って戻るべきですね。




//2.order by values
    var k = Object.values(dict);
    k.sort();
    k = k.reverse();
    
    //3.find result
    var res = 0;
    for (let i = 0; i < k.length; i++) {
        const s = k[i];
        
        if (s>mid)
        {                
            return res == 0 ? 1 : res+1;
        }
        else if (s<mid)
        {
            mid -= s;
            res +=1;
        }
        else    //s == mid
        {
            return res+1;
        }
    }
    
    return res;

これで正しい値を返すことができるようになりました。疑問が解消されて、安心して眠れるようになりました。

今後機会があれば、ドキュメントに記載されている every() と some() も調べてみたいと思います。

結論

結論として、JavaScriptの配列の反復処理が必要な場合、forEach関数ではなくforループを使用するべきです!!



参考文献:




🧡私たちの投稿を共有してサポートしていただければ幸いです。ありがとうございます。

✅この投稿に関する問題がある場合は、お気軽にお知らせください。




0 件のコメント:

コメントを投稿

JavaScript – 配列内の最大値を取得する3つの方法

何が起こったか 最近、問題を解決している際に、JavaScriptで配列の最大値を取得する必要がありました。具体的には、 LeetCode #300 Longest Increasing Subsequence の問題に取り組んでいました。 しかし、JavaScriptはC#の ...