この前、私が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 件のコメント:
コメントを投稿