reduce() を使うと、ある配列から各要素ごとに処理を実行、一つの結果にまとめることができます。
filter() はある配列から条件にマッチした要素だけを抽出できます。
簡単な例として「Number配列の中から偶数だけを取り出してその合計を求めたい」場合を想定します。
先に forEach()
を使った場合を書いてみましょう。
forEach()
を使う場合
const myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let result = 0
myArray.forEach(value => {
if (value%2 === 0) {
result = result + value
}
})
console.log(result)
結果:
=> 20
このようにかけますね。
reduce()
, filter()
を使う場合
filter()
はわかりやすいですが reduce()
の使い方は、
myArray.reduce(reducer, initialValue)
のように使います。
reducerはcallbackを渡して、initialValueはaccumulatorの初期値になります。
reduce()
にはreducer関数(純粋関数)と言われるものを渡します。
そして reducer関数の中は第一引数にaccumulatorが渡ってきます。
これは蓄積された値、つまり要素の数だけreducer関数を実行した時に、前の関数でreturnされた値が入ります(下の例だと 2 → 6 → 12 → 20 の順)。
第二引数は実行される現在の値(下の例だと 2 → 4 → 6 ...の順)になります。
const myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const isEvenNumber = value => value%2 === 0
const reducer = (accumulator, currentValue) => accumulator + currentValue
const result = myArray.filter(isEvenNumber).reduce(reducer, 0)
console.log(result)
結果:
=> 20
結果は同じですね。
まとめ
forEach()
の例と比べるとわかりますが、 reduce()
や filter()
、 map()
を使うとループ処理部分を別関数として切り出しやすくなります。
これによってロジックを共通化できたり、テストが書きやすくなるというメリットがあるので、reduce()
や filter()
、 map()
を積極的に使っていきたいですね。