在数据处理中,经常需要将数组元素按照特定属性或规则进行分组归类。在过去,开发者通常不得不手写 reduce 函数或者引入 Lodash 等第三方库来实现这一功能。ES2024 引入了 Array.prototype.groupBy 方法,让这一操作变得像调用 map 或 filter 一样简单。
1. 理解 groupBy 的核心逻辑
groupBy 方法接收一个回调函数,该函数为每个数组元素返回一个“键”。方法最终返回一个普通对象,对象的属性名就是这些“键”,属性值是对应的元素数组。
执行以下操作来理解其工作流程:
- 准备一个包含多个对象的数组。
- 调用
groupBy方法。 - 在回调函数中,指定分组的依据。
- 方法遍历数组,将每个元素放入对应的键值下。
以下流程图展示了数据流转的过程:
graph LR
A[输入数组] --> B(groupBy 回调)
B -- "返回 Key: A" --> C[组 A]
B -- "返回 Key: B" --> D[组 B]
B -- "返回 Key: A" --> C
C --> E{最终结果对象}
D --> E
E --> F["{ 'A': [...], 'B': [...] }"]
2. 场景实战:电商库存状态分类
假设你正在开发一个电商后台管理系统,需要将商品列表按照库存状态分为“有货”、“库存紧张”和“缺货”三类。
输入以下代码到控制台或代码编辑器中:
const products = [
{ name: '机械键盘', stock: 120 },
{ name: '无线鼠标', stock: 5 },
{ name: '高清显示器', stock: 0 },
{ name: 'USB转接器', stock: 42 },
{ name: '笔记本电脑', stock: 8 }
];
编写分组逻辑:
const groupedStock = products.groupBy((product) => {
if (product.stock === 0) return '缺货';
if (product.stock < 10) return '库存紧张';
return '有货';
});
打印结果查看分类效果:
console.log(groupedStock);
你将得到一个结构清晰的对象,其中包含了三个键:缺货、库存紧张 和 有货,每个键对应的值都是商品数组。
3. 进阶应用:用户数据按年龄段统计
在用户分析报表中,通常需要将用户数据按照年龄段进行划分,以便计算不同年龄段的活跃度。
定义用户数据源:
const users = [
{ id: 1, name: 'Alice', age: 17 },
{ id: 2, name: 'Bob', age: 23 },
{ id: 3, name: 'Charlie', age: 35 },
{ id: 4, name: 'David', age: 42 },
{ id: 5, name: 'Eve', age: 16 },
{ id: 6, name: 'Frank', age: 65 }
];
使用 groupBy 进行年龄段划分:
const usersByAgeGroup = users.groupBy((user) => {
const age = user.age;
if (age < 18) return '未成年';
if (age >= 18 && age < 60) return '成年人';
return '老年人';
});
验证分组结果:
console.log(usersByAgeGroup['成年人']);
// 输出: [{ id: 2, name: 'Bob', age: 23 }, ...]
通过这种方式,你可以直接通过 usersByAgeGroup['成年人'] 访问特定群组的用户,无需再编写复杂的循环查找代码。
4. 注意事项:对象属性名的限制
groupBy 返回的是一个普通 JavaScript 对象。这意味着分组的键(Key)会被强制转换为字符串。
如果你的分组依据可能是数字或 Symbol,需要注意类型转换的问题。如果需要保留原始类型的键,或者需要键是对象,请使用 Array.prototype.groupByToMap,它返回一个 Map 对象。
对比两者的差异:
| 特性 | groupBy |
groupByToMap |
|---|---|---|
| 返回类型 | 普通对象 | Map 对象 |
| 键的类型 | 强制转换为字符串 | 保留原始类型 |
| 使用场景 | 键为字符串或数字,需序列化传输 | 键可能为对象或需保持唯一性 |
选择合适的方法:
- 当分组键是简单的分类名称(如“已售出”、“未售出”)时,使用
groupBy。 - 当分组键可能是对象本身,或者你需要更灵活的键类型时,使用
groupByToMap。

暂无评论,快来抢沙发吧!