reduce とは
reduce
メソッドとは、「配列内の要素を順番に処理して、1つの結果を算出するヤツ」です。
以下では、配列numbers
の数値の合計値を算出しています。
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
}, 0);
console.log(sum); // 15
個人的にreduce
メソッドは、引数の多さや、複雑な見た目からJavaScriptの配列メソッドの中でも最難関だと思っています。
破壊的 or 非破壊的
reduce
メソッドは、非破壊的メソッドです。使用しても、操作元の配列に影響は及びません。
JavaScriptの配列メソッドには、実行した際に元の配列やオブジェクトそのものを変更する「破壊的メソッド」と、元の配列やオブジェクトを変更せずに新しい配列やオブジェクトを作成して返す「非破壊的メソッド」の2種類があります。
使用したい配列メソッドが「破壊的」なのか「非破壊的」なのかが考慮できていない為にバグが発生することはよくあるので、使用する際には確認しておきましょう。
こちらのサイトで詳しく説明されていますので、併せてご確認ください。
使い方(基本)
まずはreduce
メソッドを複雑にしている引数について、1つずつ整理して説明します。
reduce
メソッドには、引数は2つ渡します。(★:重要度高 ◼︎:重要度低)
- ★「コールバック関数」:配列の各要素に対して実行される関数。ここで
return
された値が次の回の「accumulator」になる - ★「『accumulator』の初期値」:後述する「accumulator」の初期値
👆の1つ目で渡している「コールバック関数」には、引数を最大4つ渡します(🥵)。(★:重要度高 ◼︎:重要度低)
- ★「accumulator」:前回の呼び出しの戻り値
- ★「currentValue」:現在の配列要素
- ◼︎「currentIndex」:現在の配列要素のインデックス
- ◼︎「array」:実行対象の配列そのもの
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
}, 0);
console.log(sum); // 15
例で提示した上記のプログラムに合わせて説明すると、
-
accumulator
に、「『accumulator』の初期値」として指定された「0」が代入される -
currentValue
は配列numbers
の1個目の要素「1」なので、accumulator
(初期値「0」)にcurrentValue
「1」を足した値、「1」をreturn
する(accumulator
に代入する) -
currentValue
は配列numbers
の2個目の要素「2」なので、accumulator
「1」にcurrentValue
「2」を足した値、「3」をreturn
する(accumulator
に代入する) -
currentValue
は配列numbers
の3個目の要素「3」なので、accumulator
「3」にcurrentValue
「3」を足した値、「6」をreturn
する(accumulator
に代入する) -
currentValue
は配列numbers
の4個目の要素「4」なので、accumulator
「6」にcurrentValue
「4」を足した値、「10」をreturn
する(accumulator
に代入する) -
currentValue
は配列numbers
の5個目の要素「5」なので、accumulator
「10」にcurrentValue
「5」を足した値、「15」をreturn
する(accumulator
に代入する) - 最終的な
accumulator
の値「15」がreduce
メソッドの結果として返されて、変数sum
に「15」が 代入される
このように、配列の要素を使用して何か1つの結果を算出したい場合に、reduce
メソッドを使用します。
reduce
メソッドを見つけた際には、
- 第二引数に注目して「accumulator」の初期値は何か確認する
- コールバック関数内で何を
return
しているかに注目して、「accumulator」に対してどんな操作を行なっているかを確認する
という点に注目してみると、頭が整理されて見やすくなるかと思います。
使い方(応用)
オブジェクト配列を扱う
const items = [
{ name: 'apple', price: 50 },
{ name: 'banana', price: 30 },
{ name: 'orange', price: 20 }
];
const totalPrice = items.reduce((accumulator, currentValue) => {
return accumulator + currentValue.price;
}, 0);
console.log(totalPrice); // 100
オブジェクトを生成する
算出結果「accumulator」はシンプルな数値である必要はありません。以下のように、オブジェクトを生成することも可能です。
以下のプログラムでは、配列fruits
の各要素を数えて、それぞれのフルーツの出現回数を持つオブジェクトfruitCount
を作成しています。
const fruits = ['apple', 'banana', 'orange', 'apple', 'orange', 'banana', 'banana'];
const fruitCount = fruits.reduce((accumulator, currentValue) => {
if (accumulator[currentValue]) {
accumulator[currentValue]++;
} else {
accumulator[currentValue] = 1;
}
return accumulator;
}, {});
console.log(fruitCount); // { apple: 2, banana: 3, orange: 2 }