この前、私が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ループを使用するべきです!!
参考文献:
- Array.prototype.forEach() - JavaScript | MDN (mozilla.org)
- Object.values() - JavaScript | MDN (mozilla.org)
🧡私たちの投稿を共有してサポートしていただければ幸いです。ありがとうございます。
✅この投稿に関する問題がある場合は、お気軽にお知らせください。
0 件のコメント:
コメントを投稿