はじめに
JavaScript ES2024で新しく追加されたObject.groupBy()は、配列のグループ化処理を劇的にシンプルにする新機能です。従来ではreduce()や外部ライブラリで実装していた処理が、ネイティブ機能でより安全かつ直感的に書けるようになりました。
Object.groupBy()とは
Object.groupBy()は、配列などの反復可能なオブジェクトを指定した条件でグループ化し、オブジェクトとして返すメソッドです。
基本的な構文
Object.groupBy(items, callbackFn)
-
items: グループ化したい配列などのiterable -
callbackFn: 各要素に対して実行される関数(戻り値はグループ化のキー)
使用例
const fruits = ["apple", "banana", "apricot", "cherry", "blueberry"];
// 最初の文字でグループ化
const groupedByFirstLetter = Object.groupBy(fruits, (fruit) => fruit[0]);
console.log(groupedByFirstLetter);
// 出力:
// {
// a: ["apple", "apricot"],
// b: ["banana", "blueberry"],
// c: ["cherry"]
// }
reduce()との比較
同じ処理をreduce()で実装した場合と比較してみます。
reduce()を使った従来の方法
const inventory = [
{ name: "asparagus", type: "vegetable", quantity: 5 },
{ name: "bananas", type: "fruit", quantity: 0 },
{ name: "cherries", type: "fruit", quantity: 5 },
{ name: "broccoli", type: "vegetable", quantity: 2 },
];
// reduce()での実装
const groupedWithReduce = inventory.reduce((acc, item) => {
const key = item.type;
// キーが存在しなければ空の配列で初期化
if (!acc[key]) {
acc[key] = [];
}
// 現在の要素をキーの配列に追加
acc[key].push(item);
return acc;
}, {}); // 初期値として空のオブジェクトを渡す
Object.groupBy()を使った新しい方法
// Object.groupBy()での実装(たった1行!)
const groupedWithGroupBy = Object.groupBy(inventory, ({ type }) => type);
console.log(groupedWithGroupBy);
// 出力:
// {
// vegetable: [
// { name: "asparagus", type: "vegetable", quantity: 5 },
// { name: "broccoli", type: "vegetable", quantity: 2 }
// ],
// fruit: [
// { name: "bananas", type: "fruit", quantity: 0 },
// { name: "cherries", type: "fruit", quantity: 5 }
// ]
// }
とてもシンプルですね!
比較まとめ
| 項目 | Object.groupBy() | reduce() |
|---|---|---|
| コードの簡潔さ | 1行で記述可能 | 定型的な処理が必要で冗長 |
| 可読性 | 「グループ化」の意図が明確 | コードを読まないと目的が分からない |
| 返り値 | nullプロトタイプオブジェクト(安全) | 通常のオブジェクト |
| エラー回避 | キーの存在確認が不要 | キーの存在確認を忘れがち |
活用例
1. ユーザーデータを年代別でグループ化する
const users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 35 },
{ name: "Charlie", age: 28 },
{ name: "Diana", age: 42 },
{ name: "Eve", age: 31 }
];
// 年代別にグループ化
const groupedByGeneration = Object.groupBy(users, (user) => {
if (user.age < 30) return "20代";
if (user.age < 40) return "30代";
return "40代以上";
});
console.log(groupedByGeneration);
// 出力:
// {
// "20代": [{ name: "Alice", age: 25 }, { name: "Charlie", age: 28 }],
// "30代": [{ name: "Bob", age: 35 }, { name: "Eve", age: 31 }],
// "40代以上": [{ name: "Diana", age: 42 }]
// }
2. 売上データを月別集計する
const sales = [
{ product: "A", date: "2025-01-15", amount: 1000 },
{ product: "B", date: "2025-01-20", amount: 1500 },
{ product: "A", date: "2025-02-10", amount: 800 },
{ product: "C", date: "2025-02-15", amount: 2000 },
{ product: "B", date: "2025-03-05", amount: 1200 }
];
// 月別にグループ化
const groupedByMonth = Object.groupBy(sales, (sale) =>
sale.date.substring(0, 7) // "2025-01" 形式で月を抽出
);
console.log(groupedByMonth);
// 出力:
// {
// "2024-01": [
// { product: "A", date: "2025-01-15", amount: 1000 },
// { product: "B", date: "2025-01-20", amount: 1500 }
// ],
// "2024-02": [
// { product: "A", date: "2025-02-10", amount: 800 },
// { product: "C", date: "2025-02-15", amount: 2000 }
// ],
// "2024-03": [
// { product: "B", date: "2025-03-05", amount: 1200 }
// ]
// }
3. タスクを優先度別にグループ化する
const tasks = [
{ title: "バグ修正", priority: "high", status: "pending" },
{ title: "機能追加", priority: "medium", status: "in-progress" },
{ title: "ドキュメント更新", priority: "low", status: "completed" },
{ title: "セキュリティ対応", priority: "high", status: "pending" },
{ title: "コードレビュー", priority: "medium", status: "pending" }
];
// 優先度別にグループ化
const groupedByPriority = Object.groupBy(tasks, ({ priority }) => priority);
// 各グループのタスク数を確認
Object.entries(groupedByPriority).forEach(([priority, taskList]) => {
console.log(`${priority}: ${taskList.length}件`);
});
// 出力:
// high: 2件
// medium: 2件
// low: 1件
ブラウザサポート状況
Object.groupBy()は比較的新しい機能ですが、主要ブラウザでは対応済みです。
サポート済み:
- Chrome 117以降
- Firefox 119以降
- Safari 17.2以降
- Edge 117以降
- Node.js 21.0.0以降
- Deno 1.37以降
古いブラウザをサポートする必要がある場合は、core-jsなどのPolyfillを使用してください。
まとめ
Object.groupBy()は、JavaScriptにおける配列のグループ化処理を大幅に改善する素晴らしい機能ということがおわかりいただけたかと思います!
主なメリット:
- コードの簡潔性: 1行で直感的にグループ化が可能
- 可読性の向上: 意図が明確で保守しやすいコード
- 安全性: nullプロトタイプオブジェクトによる予期しないプロパティ継承の回避
- エラー削減: キーの存在確認などの定型処理が不要
データ処理やレポート生成、UI表示用のデータ変換など、様々な場面で活用できる実用的な機能です。積極的に活用して、より読みやすく保守しやすいコードを書いていきましょう!