如何用原生JS将分组对象数组转换为简洁对象数组
原生JavaScript实现数组结构转换(无需lodash)
需求说明
原始数组:
const arr = [ { "name": "mac" }, { "group": "others", "name": "lenovo" }, { "group": "others", "name": "samsung" } ]
需要转换为:
[ { name: 'mac', }, { name: 'others', group: [ { name: 'lenovo', }, { name: 'samsung', }, ], } ]
核心要求:将带有相同group属性的元素合并为一个分组对象,无group属性的元素直接保留。
原forEach代码的问题
你之前的forEach实现存在两个关键问题:
- 每次遇到带
group的元素都会新建空数组并直接push到结果,导致相同group的元素被拆分成多个独立数组,没有合并。 group变量未用let/const声明,属于全局变量,会引发意外覆盖。
用reduce实现的方案
可以用数组的reduce方法高效完成转换,代码如下:
const arr = [ { "name": "mac" }, { "group": "others", "name": "lenovo" }, { "group": "others", "name": "samsung" } ]; const final = arr.reduce((acc, item) => { // 无group属性的元素直接加入结果 if (!item.group) { acc.push(item); return acc; } // 查找当前group对应的分组对象是否已存在 const existingGroup = acc.find(ele => ele.name === item.group); if (existingGroup) { // 已存在则往分组数组中添加新元素 existingGroup.group.push({ name: item.name }); } else { // 不存在则新建分组对象并加入结果 acc.push({ name: item.group, group: [{ name: item.name }] }); } return acc; }, []); console.log(final);
逻辑说明
- 初始化累加器
acc为空数组,作为最终结果的容器。 - 遍历每个元素:
- 无
group的元素直接推入结果数组。 - 有
group的元素,先检查结果数组中是否已存在对应分组(通过name匹配group值)。 - 存在则向该分组的
group数组添加元素;不存在则创建新的分组对象并推入结果数组。
- 无
修复后的forEach实现
如果坚持用forEach,也可以通过一个辅助对象记录已创建的分组,避免重复查找:
let final = []; const groupMap = {}; // 记录已存在的分组对象 arr.forEach(o => { if (!o.group) { final.push(o); } else { if (!groupMap[o.group]) { // 新建分组对象并加入结果和映射表 const groupObj = { name: o.group, group: [] }; groupMap[o.group] = groupObj; final.push(groupObj); } // 向对应分组添加元素 groupMap[o.group].group.push({ name: o.name }); } }); console.log(final);
内容的提问来源于stack exchange,提问作者Jenny Le
相关产品推荐
相关产品推荐

