如何按公共字段重组对象数组?使用reduce未获预期格式
问题:将JavaScript数组按box分组并转换为指定结构
原始数组
var a = [ { "box":"1", "product":"Pen", "color":"White" }, { "box":"1", "product":"Pencil", "color":"Blue" }, { "box":"1", "product":"Marker", "color":"Red" }, { "box":"2", "product":"Paper", "color":"White"}, { "box":"2", "product":"GlossPaper", "color":"Yellow"}, { "box":"3", "product":"Eraser", "color":"Pink"} ];
想要的目标结构
a = { "box": [ { "number": "1", "contents": [ {"product": "Pen", "color": "White"}, {"product": "Pencil", "color": "Blue"}, {"product": "Marker", "color": "Red"} ] }, { "number": "2", "contents": [ {"product": "Paper", "color": "White"}, {"product": "GlossPaper", "color": "Yellow"} ] }, { "number": "3", "contents": [ {"product": "Eraser", "color": "Pink"} ] } ] }
我尝试的代码(没得到预期结果)
a = a.reduce(function(x, e) { var estKey = (e['box']); (x[estKey] ? x[estKey] : (x[estKey] = null || [])).push(e); return x; }, {});
正确实现代码
调整reduce的逻辑,先按box值分组,再转换成目标结构:
const result = a.reduce((acc, item) => { // 查找当前box对应的分组 let boxGroup = acc.box.find(group => group.number === item.box); if (!boxGroup) { // 没找到就新建分组并加入数组 boxGroup = { number: item.box, contents: [] }; acc.box.push(boxGroup); } // 提取product和color加入contents boxGroup.contents.push({ product: item.product, color: item.color }); return acc; }, { box: [] }); // 更新原变量a a = result;
代码说明
- 初始化累加器为
{ box: [] },和目标结构的外层保持一致 - 遍历每个元素时,先检查是否已有对应
number的分组 - 没有的话创建新分组对象,包含
number和空的contents数组,再推入acc.box - 把当前元素的
product和color提取出来,添加到对应分组的contents数组中 - 最终返回的累加器就是你要的结构
内容的提问来源于stack exchange,提问作者BaaBaa Black Sheep
相关产品推荐
相关产品推荐

