🗺️
reduceとMapを組み合わせてコードをすっきりさせる
Mapを作りたい時
テーブルからfecthしたデータをMap化して高速にアクセスしたいケースはよくあると思います。
そのMapを作る時、reduceを使わない場合はこうなるかと。
const users = await fetch("http://example.com/users");
const userMap = new Map<string, UserEntity>();
users.forEach((user) => {
userMap.set(user.id, user)
})
reduceを使うとちょっとすっきりします
const users = await fetch("http://example.com/users");
const userMap = users.reduce((accum, current) => {
accum.set(current.id, current)
}, new Map<string, UserEntity>())
単純な数の集計をしたい
reduce,Mapの組み合わせで集計もすっきり記述できるかと思います。
const result = [
{ category: "x", count: 10 },
{ category: "x", count: 10 },
{ category: "y", count: 10 },
{ category: "x", count: 10 },
{ category: "z", count: 10 },
{ category: "y", count: 10 }
];
const sum = result.reduce((accum, current) => {
accum.set(current.category, (accum.get(current.category) ?? 0) + current.count);
return accum;
}, new Map());
console.log(sum);
/* 結果は以下の通り
Map {}
x: 30
y: 20
z: 10
*/
<追記:2023/12/03>
集計をする場合はgroupByを使うと良いケースも
Discussion
categoryにx,y,z以外がきたときに、処理を途中で止めてください。
という仕様がきたときに100万項目とかある場合に、reduceは対応しきれなくて
仕様変更に弱いため、下記のごくごく自然なループコードの方がよいと思います。
全量が見切れているケースでしか使うべきではないでしょうね。