ECMAScript 2024 (ES15) 引入了一個極具潛力的新特性:Map.groupBy(),它大大簡化了數據分組的操作。無論是在處理數組、對象,還是更復雜的業務邏輯中,分組操作都是開發中常見的需求。本文將通過詳細的技術案例和代碼展示,為你剖析 Map.groupBy() 的強大之處。
什麼是 Map.groupBy()?
Map.groupBy() 是 JavaScript 新增的靜態方法,用於從一個可迭代對象(如數組)中創建一個 Map,並根據指定的分組邏輯,將數據分組到對應的鍵中。每個鍵對應一個數組,包含所有被分到該組的數據。
語法如下:
Map.groupBy(iterable, callbackFn)
- iterable: 任何可迭代對象(如數組、字符串等)。
- callbackFn: 回調函數,用於生成分組的鍵。格式為
callbackFn(element, index)。
返回值是一個 Map,其中:
- 鍵是分組鍵,由
callbackFn決定。 - 值是一個數組,包含屬於該組的所有元素。
目前該新特性兼容性如下:
使用場景解析
1. 按條件分組
假設我們有一個學生成績數組,想按成績的及格與否進行分組。
const scores = [
{ name: 'Alice', score: 85 },
{ name: 'Bob', score: 40 },
{ name: 'Charlie', score: 90 },
{ name: 'Dave', score: 30 }
];
const groupedByPass = Map.groupBy(scores, student => student.score >= 60 ? 'pass' : 'fail');
console.log(groupedByPass);
// 輸出:
// Map {
// 'pass' => [
// { name: 'Alice', score: 85 },
// { name: 'Charlie', score: 90 }
// ],
// 'fail' => [
// { name: 'Bob', score: 40 },
// { name: 'Dave', score: 30 }
// ]
// }
這裏,callbackFn 返回的鍵是字符串 'pass' 或 'fail',分別對應及格與不及格的分組。
2. 按屬性分組
我們有一個商品列表,希望根據商品的類別進行分組:
const products = [
{ name: 'Laptop', category: 'Electronics' },
{ name: 'Phone', category: 'Electronics' },
{ name: 'Shirt', category: 'Clothing' },
{ name: 'Pants', category: 'Clothing' }
];
const groupedByCategory = Map.groupBy(products, product => product.category);
console.log(groupedByCategory);
// 輸出:
// Map {
// 'Electronics' => [
// { name: 'Laptop', category: 'Electronics' },
// { name: 'Phone', category: 'Electronics' }
// ],
// 'Clothing' => [
// { name: 'Shirt', category: 'Clothing' },
// { name: 'Pants', category: 'Clothing' }
// ]
// }
這種分組方式非常適合電商、庫存管理等場景。
3. 複雜鍵的分組
分組鍵不僅限於簡單的字符串,也可以是對象或其他複雜類型。
const events = [
{ title: 'Meeting', date: new Date('2025-01-01') },
{ title: 'Conference', date: new Date('2025-01-02') },
{ title: 'Workshop', date: new Date('2025-01-01') }
];
const groupedByDate = Map.groupBy(events, event => event.date.toISOString());
console.log(groupedByDate);
// 輸出:
// Map {
// '2025-01-01T00:00:00.000Z' => [
// { title: 'Meeting', date: 2025-01-01T00:00:00.000Z },
// { title: 'Workshop', date: 2025-01-01T00:00:00.000Z }
// ],
// '2025-01-02T00:00:00.000Z' => [
// { title: 'Conference', date: 2025-01-02T00:00:00.000Z }
// ]
// }
callbackFn 使用了 toISOString() 方法,將日期對象轉換為字符串形式,方便作為分組鍵。
深入對比 reduce 的替代性
在 Map.groupBy() 推出之前,我們通常使用 reduce 來實現分組操作。
以下是用 reduce 實現的分組代碼:
const scores = [
{ name: 'Alice', score: 85 },
{ name: 'Bob', score: 40 },
{ name: 'Charlie', score: 90 },
{ name: 'Dave', score: 30 }
];
const groupedByReduce = scores.reduce((group, student) => {
const key = student.score >= 60 ? 'pass' : 'fail';
if (!group[key]) {
group[key] = [];
}
group[key].push(student);
return group;
}, {});
console.log(groupedByReduce);
// 輸出:
// {
// pass: [
// { name: 'Alice', score: 85 },
// { name: 'Charlie', score: 90 }
// ],
// fail: [
// { name: 'Bob', score: 40 },
// { name: 'Dave', score: 30 }
// ]
// }
雖然 reduce 功能強大,但使用起來容易冗長,Map.groupBy() 則更簡潔優雅,並且返回的是 Map 對象,提供了更多操作的可能性。
性能與最佳實踐
性能
-
Map.groupBy()的優勢:Map的鍵可以是任意值(包括對象),而Object的鍵只能是字符串或符號。Map的鍵值查找和插入效率高,適合處理大量數據。
-
reduce的侷限:- 手動處理數據結構容易出錯。
- 性能略遜於專門為分組設計的
Map.groupBy()。
最佳實踐
- 使用
Map.groupBy()時,確保callbackFn簡單易懂,避免過於複雜的邏輯。 - 分組鍵應儘量唯一且明確,避免不必要的衝突。
小結
Map.groupBy() 是 ECMAScript 2024 中極為實用的特性,它簡化了數據分組的操作,提高了代碼的可讀性和維護性。在處理複雜分組需求時,它能讓開發者事半功倍。
如果你還在用傳統的 reduce 實現分組,不妨試試這個全新的方法,感受現代 JavaScript 的魅力!
當然你也在學習前端和鴻蒙等技術,不妨關注我,我們一起學習進步。(≧▽≦)/