深入理解 ECMAScript 2024 新特性:Map.groupBy() 分組操作

ECMAScript 2024 (ES15) 引入了一個(gè)極具潛力的新特性:Map.groupBy(),它大大簡(jiǎn)化了數(shù)據(jù)分組的操作。無(wú)論是在處理數(shù)組、對(duì)象,還是更復(fù)雜的業(yè)務(wù)邏輯中,分組操作都是開(kāi)發(fā)中常見(jiàn)的需求。本文將通過(guò)詳細(xì)的技術(shù)案例和代碼展示,為你剖析 Map.groupBy() 的強(qiáng)大之處。


什么是 Map.groupBy()?

Map.groupBy() 是 JavaScript 新增的靜態(tài)方法,用于從一個(gè)可迭代對(duì)象(如數(shù)組)中創(chuàng)建一個(gè) Map,并根據(jù)指定的分組邏輯,將數(shù)據(jù)分組到對(duì)應(yīng)的鍵中。每個(gè)鍵對(duì)應(yīng)一個(gè)數(shù)組,包含所有被分到該組的數(shù)據(jù)。

語(yǔ)法如下:

Map.groupBy(iterable, callbackFn)
  • iterable: 任何可迭代對(duì)象(如數(shù)組、字符串等)。
  • callbackFn: 回調(diào)函數(shù),用于生成分組的鍵。格式為 callbackFn(element, index)。

返回值是一個(gè) Map,其中:

  • 鍵是分組鍵,由 callbackFn 決定。
  • 值是一個(gè)數(shù)組,包含屬于該組的所有元素。

目前該新特性兼容性如下:


Map.groupBy() 目前兼容狀態(tài)

使用場(chǎng)景解析

1. 按條件分組

假設(shè)我們有一個(gè)學(xué)生成績(jī)數(shù)組,想按成績(jī)的及格與否進(jìn)行分組。

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',分別對(duì)應(yīng)及格與不及格的分組。


2. 按屬性分組

我們有一個(gè)商品列表,希望根據(jù)商品的類(lèi)別進(jìn)行分組:

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' }
//   ]
// }

這種分組方式非常適合電商、庫(kù)存管理等場(chǎng)景。


3. 復(fù)雜鍵的分組

分組鍵不僅限于簡(jiǎn)單的字符串,也可以是對(duì)象或其他復(fù)雜類(lèi)型。

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() 方法,將日期對(duì)象轉(zhuǎn)換為字符串形式,方便作為分組鍵。


深入對(duì)比 reduce 的替代性

Map.groupBy() 推出之前,我們通常使用 reduce 來(lái)實(shí)現(xiàn)分組操作。

以下是用 reduce 實(shí)現(xiàn)的分組代碼:

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 功能強(qiáng)大,但使用起來(lái)容易冗長(zhǎng),Map.groupBy() 則更簡(jiǎn)潔優(yōu)雅,并且返回的是 Map 對(duì)象,提供了更多操作的可能性。


性能與最佳實(shí)踐

性能

  • Map.groupBy()的優(yōu)勢(shì)

    • Map 的鍵可以是任意值(包括對(duì)象),而 Object 的鍵只能是字符串或符號(hào)。
    • Map 的鍵值查找和插入效率高,適合處理大量數(shù)據(jù)。
  • reduce 的局限

    • 手動(dòng)處理數(shù)據(jù)結(jié)構(gòu)容易出錯(cuò)。
    • 性能略遜于專(zhuān)門(mén)為分組設(shè)計(jì)的 Map.groupBy()。

最佳實(shí)踐

  • 使用 Map.groupBy() 時(shí),確保 callbackFn 簡(jiǎn)單易懂,避免過(guò)于復(fù)雜的邏輯。
  • 分組鍵應(yīng)盡量唯一且明確,避免不必要的沖突。

小結(jié)

Map.groupBy() 是 ECMAScript 2024 中極為實(shí)用的特性,它簡(jiǎn)化了數(shù)據(jù)分組的操作,提高了代碼的可讀性和維護(hù)性。在處理復(fù)雜分組需求時(shí),它能讓開(kāi)發(fā)者事半功倍。

如果你還在用傳統(tǒng)的 reduce 實(shí)現(xiàn)分組,不妨試試這個(gè)全新的方法,感受現(xiàn)代 JavaScript 的魅力!

當(dāng)然你也在學(xué)習(xí)前端和鴻蒙等技術(shù),不妨關(guān)注我,我們一起學(xué)習(xí)進(jìn)步。(≧▽≦)/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容