JavaScript Object.groupBy() 與 Map.groupBy()
在處理資料陣列時,我們經常需要根據某個屬性(如:類別、狀態、年份)對資料進行「分組」(Grouping)。
在 ES2024 之前,我們通常必須自己寫 reduce() 或 forEach() 來手動建立一個物件或 Map 來存放分組後的資料。現在,JavaScript 內建了 Object.groupBy() 和 Map.groupBy() 讓這件事變得異常簡單。
Object.groupBy()
Object.groupBy() 會回傳一個普通的 JavaScript 物件,物件的鍵 (Key) 是分組的標籤,值 (Value) 是該分組對應的元素陣列。
範例:依類別分類水果
const inventory = [
{ name: 'asparagus', type: 'vegetables', quantity: 5 },
{ name: 'bananas', type: 'fruit', quantity: 0 },
{ name: 'goat', type: 'meat', quantity: 23 },
{ name: 'cherries', type: 'fruit', quantity: 5 },
{ name: 'fish', type: 'meat', quantity: 22 },
];
const result = Object.groupBy(inventory, ({ type }) => type);
/* 輸出結果:
{
vegetables: [
{ name: "asparagus", type: "vegetables", quantity: 5 }
],
fruit: [
{ name: "bananas", type: "fruit", quantity: 0 },
{ name: "cherries", type: "fruit", quantity: 5 }
],
meat: [
{ name: "goat", type: "meat", quantity: 23 },
{ name: "fish", type: "meat", quantity: 22 }
]
}
*/
Map.groupBy()
Map.groupBy() 的運作方式與 Object.groupBy() 幾乎一模一樣,但它回傳的是一個 Map 物件。
這在你需要使用「非字串」作為鍵(例如使用物件作為 Key)的時候非常有用。
範例:依庫存狀態分類
const stockStatus = { ok: '庫存充足', low: '庫存低' };
const inventory = [
{ name: 'Item A', quantity: 10 },
{ name: 'Item B', quantity: 2 },
{ name: 'Item C', quantity: 15 },
];
const result = Map.groupBy(inventory, ({ quantity }) => {
return quantity > 5 ? stockStatus.ok : stockStatus.low;
});
// 你可以透過物件作為 Key 來取得資料
console.log(result.get(stockStatus.ok));
// 輸出 [{ name: "Item A", quantity: 10 }, { name: "Item C", quantity: 15 }]
為什麼要用 groupBy?
- 可讀性極佳: 代碼意圖非常明顯(我要分組)。
- 效能優化: 比自己寫的
reduce邏輯更簡潔,且引擎內部可能會有針對性的優化。 - 符合直覺: 這是現代資料處理中最常見的需求之一,現在終於有了標準做法。
總結
Object.groupBy() 是處理 JSON 資料或一般物件陣列的首選;而如果你有更複雜的鍵值需求或需要 Map 的特性,則選用 Map.groupBy()。這兩個新工具極大地簡化了 JavaScript 的資料操作邏輯。