冒頭でもお伝えしましたが、reduceメソッドは配列に対して使用するメソッドで、配列のすべての要素を1つの値にまとめるときに使うメソッドです。
array.reduce((accumulator, currentValue, currentIndex, array) => {
return // 処理内容
}, initialValue);
処理内容をreturnを使って、処理を返すことでaccumulator(累積値)に結果が保持されて、1つの値となって取得できるというわけですね。
初歩的な配列の合計であればこんな感じですね。
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, current) => { //acc は毎回の合計値 current は現在の数
return acc + current;
}, 0); // 初期値 0 から始まり、順に加算。
console.log(sum); // → 15
初オブジェクト配列からになると少しreduceの面白さがわかりますね。
const items = [
{ shopping: "にんじん", price: 200 },
{ shopping: "キャベツ", price: 290 },
{ shopping: "なすび", price: 180 },
];
const total = items.reduce((acc, item) => {
return acc + item.price; //acc は毎回の合計値 item.price は各要素の金額部分
}, 0);
console.log(total); // → 670
先日ある経費管理のフロント改修で、json_encodeより変換されたJSON形式のデータを各部署・各経費(税込・税抜表示)ごとに分け、各部署経費合計と全体の合計を管理画面に追加という作業がありました。こういう作業にreduceはオブジェクトの集計に本領発揮します。本題としました初期化についても紹介させていただきます。下記は参考として合計を出す集計コードです。
const expenses = [
{ subject: '通信費', amount: 1000 },
{ subject: '接待交際費', amount: 2500 },
{ subject: '通信費', amount: 2500 },
{ subject: '消耗品費', amount: 300 },
{ subject: '接待交際費', amount: 1500 },
{ subject: '消耗品費', amount: 400 },
];
const result = expenses.reduce((acc, item) => {
if (!acc[item.subject]) {
acc[item.subject] = 0;
}
acc[item.category] += item.amount;
return acc;
}, {});
console.log(result); // -> { "通信費": 3500, "接待交際費": 4000, "消耗品費": 700 }
経費ですのでカテゴリ分類もありますし消費税もありますので、上記のような単純な話ではないですが基本は同じです。一覧を表示したい場合もreduceメソッド使って処理の中で
const listHtml = expenses.reduce((acc, item) => {
return acc + `<li>・${item.subject} - ${item.amount}円</li>`;
}, '');
document.getElementById('lists').innerHTML = `<ul>${listHtml}</ul>`;
こんな感じですかね。合計出すのもそのままな説明ですが
const Total = expenses.reduce((sum, item) => {
return sum + item.amount;
}, 0);
こんな感じですかね。
で記事本題ですね。上記のコードの中で
if (!acc[item.subject]) {
acc[item.subject] = 0;
}
これは、reduceメソッドでよく使用する「初期化」です。処理の目的は、まだ acc の中にitem.subject( "通信費" や "接待交際費")というキーが存在していなければ、0で初期化する という処理です。これがなければ今回のコードは成立しません。
なぜ初期化が必要かと下記の状況を見てみましょう。
// → expenses の1つ目の要素
item = { subject: '通信費', amount: 1000 }
acc = {}
このときacc['通信費'] は存在しないので、次のように初期化します
if (!acc['通信費']) {
acc['通信費'] = 0;
}
この初期化がないと、存在しないキーに対して +=(加算)するとundefinedやNaNになります。なので、上記の初期化をすることで、エラーなく次のコードで加算ができるようになります。
acc['通信費'] += 1000; // → 0 + 1000 = 1000
いかがでしょうか。つまり、まだこのカテゴリに合計金額を記録してなければ0で始めてというお約束的なものです。ちなみに通信費が2回ありますが、2回目のときはacc['通信費'] はすでにあるので初期化はスキップされて同カテゴリとして加算されていきます。
いかがでしたでしょうか。今回はreduce()メソッドについてご紹介させていただきました。reduce()は配列内の数値や文字列を累積して1つの値にすることができるなど多機能性より、様々な問題解決に活用できます。応用的な使い方の解説より実践的な使用のきっかけになれば幸いです。
以上となります。できる限りわかりやすく伝えようとしても書くのは難しいです。
コードや記事の書き方について気になるところがあれば、アドバイスいただけると嬉しいです。
要件定義からブラッシュアップ/実装運用まで一貫して担当。また内部対策を中心に、GTM・GA4・Looker Studioと分析・改善案の策定も進めています。北緯43度マルチエンジニア