配列の合計値を出したいときなどに便利なreduce()
。
基本的な使い方は以下。
const arr = [1, 2, 3, 4, 5];
console.log(arr.reduce((n, m) => n + m));
// 15
勉強をしていて、「なんとなく合計値を出せるもの」という理解をもう一歩深められましたのでシェアします。
reduce()の構文と処理内容
僕がいつもお世話になっているMDNによると、構文は次の通りです。
arr.reduce(callback( accumulator, currentValue[, index[, array]] ) { // return result from executing something for accumulator or currentValue }[, initialValue]);
参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
callback
:配列のすべての要素に対して実行される関数
accumulator
:reduce()の返り値を記憶する一時的な変数(繰り返しにおける前回の実行結果)
currentValue
:現在処理される配列要素
最初の例だとそれぞれが次のように対応しています。
callback
:(n, m) => n + m
accumulator
:n
currentValue
:m
そして、反復処理の実行手順をひとつひとつ見ていくと以下のようになります。
実行回数 | n | m | 実行結果(次のn) |
---|---|---|---|
1回目 | 1 | 2 | 3 |
2回目 | 3 | 3 | 6 |
3回目 | 6 | 4 | 10 |
4回目 | 10 | 5 | 15 |
こうして簡単に配列の合計値を出すことができました。
昔C言語でint sum = 0;
で合計値を保持する変数を用意してforループを回していた時代はなんだったのか…。
どうして要素が5個なのに処理が4回なのか
要素が5つなのに処理が4回である理由は、上で紹介した構文中のinitialValue
が指定されていない場合、最初の要素を飛ばしてインデックス番号1から実行されるためです。
配列の要素の合計値を求める場合は0
を初期値として指定しておく、といった具合ですね。
MDNのドキュメントでも、通常は初期値を指定するほうが安全だと書いてあります。
より詳しく知りたい方は、ぜひドキュメントを参照してみてください。
なぜ名前が"reduce"なのか
多くの人が英単語のreduceの意味を「減らす」で覚えていますよね。
それ自体は正しいのですが、この関数reduce()
のイメージとはちょっと合致しないな~と感じます。
そこで、いまいちどreduceの意味を調べてみると、次のような意味が出てきました。
3〔+目的語+to+(代)名詞〕〈ものを〉(整理して)〔簡単な形に〕変える,まとめる.
7【数学】〈…を〉換算する,通分する,約する.
参考:https://ejje.weblio.jp/content/reduce
JavaScriptの関数で使われるreduce()
としての意味は上記のものがふさわしそうです。
reduce()
に関数を渡し、配列要素に対してその関数を実行していき、最終的に出た結果のみを返す。ふむふむ。
要素ひとつひとつをギュッとまとめてひとつの値のみにするというイメージですかね。
英単語の意味を押さえると、グッとわかりやすくなりました。