配列のメソッドであるreduce
を整理してみました。
reduceの基本形
const result = arrayData.reduce(
// 第一引数
(accumulator, currentValue, index, arr) => {},
// 第二引数
initialValue
)
// 構造がわかりやすい様に改行してます
第一引数のコールバックの引数(最大4つ):
accumulator
: 累積値(直前のループの結果)
currentValue
: 現在のループの要素
index
: 現在のループの配列インデックス *省略可
arr
: reduceが呼ぶ配列そのもの *省略可
第二引数
initialValue: accumulatorの初期値 *省略可
配列の全ての要素の和を返すreduceの一番シンプルな使い方で中身を見てみます。
const numbers = [1,2,3,4,5,6,7,8,9]
const result = numbers.reduce((accumulator, currentValue) => {
console.log("accumulator", accumulator, "currentValue", currentValue)
return accumulator + currentValue
})
console.log("result", result)
配列の0番目
がaccumulator(累積値)の初期値として使用されていることがわかります。
それ以降は1番目
から順にループして、累積値に加算しているのがわかります。
累積値の初期値に任意の値を入れたい場合は、第二引数に初期値を入れます。
const numbers = [1,2,3,4,5,6,7,8,9]
const initialValue = 0
const result = numbers.reduce((accumulator, currentValue) => {
console.log("accumulator", accumulator, "currentValue", currentValue)
return accumulator + currentValue
}, initialValue)
console.log("result", result)
これを実行すると、consoleはこう出力されます。
初期値が0になって、配列の0番目の値からループされていることがわかります。
では、全てのパラメーターをセットして実行してみます
const numbers = [1,2,3,4,5,6,7,8,9]
const result = numbers.reduce((accumulator, currentValue, index, arr) => {
console.log("accumulator", accumulator, "currentValue", currentValue, "index", index, "arr", arr)
return accumulator + currentValue
}, 0)
indexは配列の何番目を処理してるかで、arrはreduceが処理している配列データです。なのでこの2つは省略されるケースが多いです。
まとめると、reduceは配列を順にループし、各回の結果を次の呼び出しに引き継ぐ事ができるという仕組みです。そして配列のループが終わったら、累計値を返します。
forEachとの違い
forEachで以下の様に同じことできますが、reduceの方がいい理由としてはletで変数を宣言しなくていい事などが挙げられます。
const numbers = [1,2,3,4,5,6,7,8,9]
let result = 0
numbers.forEach((value) => {
result += value
})
応用
例えばこんな従業員のデータがあって、職種ごとの月間合計コストを算出したい場合、forEachで書こうとしたら大変ですが、reduceを使えば楽に書けます。
const employees = [
{ id: 'QTA01', name: '山田太郎', job: 'エンジニア', monthlySalary: 500000 },
{ id: 'QTA02', name: '鈴木大輔', job: 'エンジニア', monthlySalary: 400000 },
{ id: 'QTA03', name: '渡部秀雄', job: '営業', monthlySalary: 450000 },
{ id: 'QTA04', name: '田中花子', job: '営業', monthlySalary: 520000 },
{ id: 'QTA05', name: '岡田三郎', job: '経理', monthlySalary: 410000 },
{ id: 'QTA06', name: '田嶋圭一', job: '経理', monthlySalary: 360000 },
]
const result = employees.reduce((accumulator, currentValue) => {
if (!accumulator[currentValue.job]) {
accumulator[currentValue.job] = 0
}
accumulator[currentValue.job] += currentValue.monthlySalary
return accumulator
}, {})
結果はこうなります。
{ エンジニア: 900000, 営業: 970000, 経理: 770000 }
この様な分類と集計処理にreduceは便利です。
他にもreduceを使った便利なデータ処理は色々あると思いますので、都度追加していきます。