如何根据对象vehicule_type属性使用reduce()实现数组分组转换
JS数组按指定属性分组实现方案
注:你给出的示例存在几处笔误/语法问题:
- 原始数组中
car、plane未加引号,属于未定义变量,实际使用时需要补引号作为字符串值- 目标结构用数组
[]包裹键值对不符合JS语法,分组结果的标准结构为对象{},如果需要数组格式可以在分组完成后做一次转换- 目标结果中
mercedes项的y值写为1,和原始数据的y:2不符,以下实现保留原始数据的真实值
基于reduce()的实现(你提到的方案)
核心逻辑:
- 给
reduce传入空对象作为初始累计值 - 遍历每一项时,解构拆分出分组键
vehicule_type和剩余属性 - 判断累计对象中是否存在当前分组的数组,不存在则初始化为空数组
- 将当前项(去掉分组键后)推入对应分组数组,返回累计值进入下一轮遍历
完整代码:
const originalList = [ { x: 'bmw', vehicule_type: 'car', y: 1 }, { x: 'mercedes', vehicule_type: 'car', y: 2 }, { x: 'airbus', vehicule_type: 'plane', y: 1 } ] const groupedObj = originalList.reduce((acc, currentItem) => { // 拆分分组键和其余属性 const { vehicule_type, ...restProps } = currentItem // 初始化分组数组 if (!acc[vehicule_type]) { acc[vehicule_type] = [] } // 推入当前项 acc[vehicule_type].push(restProps) return acc }, {})
运行后得到的groupedObj结构如下,和你预期的分组逻辑完全一致:
{ car: [ { x: 'bmw', y: 1 }, { x: 'mercedes', y: 2 } ], plane: [ { x: 'airbus', y: 1 } ] }
如果你需要数组格式的结果,可以用Object.entries做一次转换:
const groupedArr = Object.entries(groupedObj) // 输出:[ ['car', [...]], ['plane', [...]] ]
更简便的原生实现(ES2024+支持)
如果你的运行环境支持ES2024标准,可以直接使用内置的Object.groupBy方法,一行代码完成分组:
// 注意:该方法返回的分组项会保留vehicule_type属性 const tempGrouped = Object.groupBy(originalList, ({ vehicule_type }) => vehicule_type) // 如果需要去掉vehicule_type属性,遍历处理一次即可 const groupedResult = Object.fromEntries( Object.entries(tempGrouped).map(([key, list]) => [ key, list.map(({ vehicule_type, ...rest }) => rest) ]) )
内容的提问来源于stack exchange,提问作者taranticoscr
相关产品推荐
相关产品推荐

