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

简介: ECMAScript 2024 (ES15) 引入了 `Map.groupBy()`,极大简化了数据分组操作。该方法从可迭代对象创建一个 `Map`,根据回调函数生成的键进行分组。适用于按条件、属性或复杂键分组,代码更简洁优雅。相比 `reduce`,它提供了更高的性能和更好的可读性,适合处理大量数据。通过详细案例展示,本文深入剖析了 `Map.groupBy()` 的强大功能及其应用场景。

ECMAScript 2024 (ES15) 引入了一个极具潜力的新特性:Map.groupBy(),它大大简化了数据分组的操作。无论是在处理数组、对象,还是更复杂的业务逻辑中,分组操作都是开发中常见的需求。本文将通过详细的技术案例和代码展示,为你剖析 Map.groupBy() 的强大之处。


什么是 Map.groupBy()

Map.groupBy() 是 JavaScript 新增的静态方法,用于从一个可迭代对象(如数组)中创建一个 Map,并根据指定的分组逻辑,将数据分组到对应的键中。每个键对应一个数组,包含所有被分到该组的数据。

语法如下:

Map.groupBy(iterable, callbackFn)
  • iterable: 任何可迭代对象(如数组、字符串等)。
  • callbackFn: 回调函数,用于生成分组的键。格式为 callbackFn(element, index)

返回值是一个 Map,其中:

  • 键是分组键,由 callbackFn 决定。
  • 值是一个数组,包含属于该组的所有元素。

目前该新特性兼容性如下:
5e6a793e-0164-49cb-8402-dde9cf1ac899.jpeg


使用场景解析

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 的魅力!

当然你也在学习前端和鸿蒙等技术,不妨关注我,我们一起学习进步。(≧▽≦)/

目录
相关文章
|
数据处理
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
242 0
|
存储 JavaScript 前端开发
ES6新特性(四): Set 和 Map
ES6新特性(四): Set 和 Map
|
存储 JavaScript 前端开发
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
136 1
|
存储 分布式计算 DataWorks
MaxCompute产品使用合集之要存储用户的下单所有产品,然后查询时要进行产品分组的,一般这种字段要使用ARRAY还是MAP
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
存储 JavaScript
ES6+新特性-Symbol与Set/Map数据结构
ES6 引入了三种新的数据结构:Symbol、Set和Map。Symbol是唯一且不可变的值,常用于定义对象的独特属性;Set存储不重复值,适合数组去重;Map则是键值对集合,键可为任意类型,提供了更灵活的存储方式。这些新数据结构提供了更高效的操作手段,分别解决了属性命名冲突、数据去重和复杂键值对存储的问题。示例展示了如何使用Symbol、Set和Map进行基本操作。
|
存储 JavaScript 前端开发
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(一)
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(一)
106 0
|
Python
Pandas进阶--map映射,分组聚合和透视pivot_table详解
Pandas进阶--map映射,分组聚合和透视pivot_table详解
365 0
|
存储 Java API
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
471 0
|
存储 前端开发 Java
Java【代码分享 13】前端动态添加一条记后端使用JDK1.8实现map对象根据key的部分值进行分组(将map对象封装成指定entity对象)
Java【代码分享 13】前端动态添加一条记后端使用JDK1.8实现map对象根据key的部分值进行分组(将map对象封装成指定entity对象)
123 0
|
Web App开发 JSON JavaScript
前端技术ES6新特性解构字符串扩展表达式箭头函数对象拓展运算符map 和 reduce Promise 模块化export import及Node.js
ECMAScript 6.0(以下简称 ES6,ECMAScript 是一种由 Ecma 国际(前身为欧洲计算机制造商协会,英文名称是 European Computer Manufacturers Association)通过 ECMA-262标准化的脚本程序设计语言)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了,并且从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015,就是 ECMAScript6。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
199 0