JSON データの集計・グルーピング
API から取得した JSON データを集計したり、特定のキーでグループ化したりする方法を解説します。reduce() メソッドを中心に、実践的なデータ処理パターンを見ていきます。
合計値の計算
reduce() を使って、配列内の数値を合計します。
const orders = [
{ product: "りんご", price: 150, quantity: 3 },
{ product: "バナナ", price: 100, quantity: 5 },
{ product: "みかん", price: 80, quantity: 10 }
];
// 合計金額
const total = orders.reduce((sum, order) => {
return sum + order.price * order.quantity;
}, 0);
console.log(total); // 1750平均値の計算
合計を要素数で割って平均を求めます。
const scores = [
{ subject: "数学", score: 80 },
{ subject: "英語", score: 75 },
{ subject: "理科", score: 90 }
];
const average = scores.reduce((sum, item) => sum + item.score, 0) / scores.length;
console.log(average); // 81.666...最大値・最小値の取得
reduce() または Math.max/min と組み合わせて求めます。
const products = [
{ name: "A", price: 1500 },
{ name: "B", price: 800 },
{ name: "C", price: 2200 }
];
// 最高価格の商品
const mostExpensive = products.reduce((max, p) =>
p.price > max.price ? p : max
);
// 価格の最大値だけを取得
const maxPrice = Math.max(...products.map(p => p.price));グループ化
特定のキーでデータをグループ化するのは、よく使うパターンです。
const users = [
{ name: "田中", department: "営業" },
{ name: "山田", department: "開発" },
{ name: "佐藤", department: "営業" },
{ name: "鈴木", department: "開発" },
{ name: "高橋", department: "人事" }
];
// 部署ごとにグループ化
const grouped = users.reduce((acc, user) => {
const key = user.department;
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(user);
return acc;
}, {});
console.log(grouped);
// {
// "営業": [{ name: "田中", ... }, { name: "佐藤", ... }],
// "開発": [{ name: "山田", ... }, { name: "鈴木", ... }],
// "人事": [{ name: "高橋", ... }]
// }Object.groupBy()(ES2024)
ES2024 では Object.groupBy() が追加され、より簡潔に書けるようになりました。
const grouped = Object.groupBy(users, user => user.department);カウント集計
各カテゴリの件数をカウントする場合です。
const votes = ["A", "B", "A", "C", "B", "A", "B", "A"];
const count = votes.reduce((acc, vote) => {
acc[vote] = (acc[vote] || 0) + 1;
return acc;
}, {});
console.log(count);
// { A: 4, B: 3, C: 1 }複数キーでの集計
複数のキーを組み合わせて集計することもできます。
const sales = [
{ year: 2023, month: 1, amount: 100 },
{ year: 2023, month: 1, amount: 150 },
{ year: 2023, month: 2, amount: 200 },
{ year: 2024, month: 1, amount: 180 }
];
// 年月ごとの合計
const monthlyTotal = sales.reduce((acc, sale) => {
const key = `${sale.year}-${sale.month}`;
acc[key] = (acc[key] || 0) + sale.amount;
return acc;
}, {});
console.log(monthlyTotal);
// { "2023-1": 250, "2023-2": 200, "2024-1": 180 }汎用的なグループ化関数
再利用しやすいグループ化関数を作っておくと便利です。
function groupBy(array, keyFn) {
return array.reduce((acc, item) => {
const key = typeof keyFn === "function" ? keyFn(item) : item[keyFn];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(item);
return acc;
}, {});
}
// 使用例
groupBy(users, "department");
groupBy(users, user => user.name[0]); // 名前の頭文字でグループ化reduce() のポイント
第2引数(初期値)を必ず指定する習慣をつけましょう。空配列の場合にエラーを防げます。
パフォーマンス
大量データの場合、reduce() は1回のループで完結するため効率的です。
集計とグループ化はデータ分析の基本です。これらのパターンを組み合わせることで、複雑なデータ処理も実現できます。