遍历嵌套对象数组生成新对象时重复项问题求助
问题描述
现有如下嵌套对象数组:
[ [ { name: 'name', prettyFormat: 'joe bloggs', uselessInfo: 'drjfghsdr' }, { name: 'email', answer: 'joe.bloggs@gmail.com', uselessInfo: 'liodrgjiwe' } ], [ { name: 'name', prettyFormat: 'mark obrien', uselessInfo: 'drjfghsdr' }, { name: 'email', answer: 'mark obrien@gmail.com', uselessInfo: 'liodrgjiwe' } ] ]
需要转换为如下格式的JSON对象:
{ "LIST": [ { "name": "joe bloggs", "email": "joe.bloggs@gmail.com" }, { "name": "mark o'brien", "email": "mark obrien@gmail.com" } ] }
编写的解决方案代码如下:
let outputBuilder = [] staffSubmissionsArray.forEach(subArray => { let personObj = {} subArray.forEach(obj => { if (obj.name == 'name') { personObj['name'] = obj.prettyFormat } if (obj.name == 'email') { personObj['email'] = obj.answer } outputBuilder.push(personObj) }) }) console.log(JSON.stringify({ "LIST" : outputBuilder }))
代码能生成正确格式的结果,但每个用户对象都出现了重复,推测是每次遍历子对象时都执行了push操作导致的,需要修复该问题,也可提供更优的实现方式。
修复方案
你的推测完全正确——问题出在内层forEach循环里每次遍历子对象都执行了outputBuilder.push(personObj),每个用户对应的子数组包含2个对象,所以每个用户会被push两次,最终导致重复。
只需要把push操作移到内层循环外面,等构建完完整的personObj之后再添加到数组即可:
let outputBuilder = [] staffSubmissionsArray.forEach(subArray => { let personObj = {} subArray.forEach(obj => { if (obj.name === 'name') { personObj.name = obj.prettyFormat } else if (obj.name === 'email') { // 改用else if减少多余判断 personObj.email = obj.answer } // 移除此处的push操作 }) // 内层循环结束后,将完整的用户对象加入数组 outputBuilder.push(personObj) }) // 加入null和2参数可格式化输出JSON,便于查看 console.log(JSON.stringify({ "LIST": outputBuilder }, null, 2))
更简洁的实现方式
可以用map和reduce组合实现,代码更简洁且符合函数式编程风格:
const result = { LIST: staffSubmissionsArray.map(subArray => subArray.reduce((person, obj) => { switch(obj.name) { case 'name': person.name = obj.prettyFormat break case 'email': person.email = obj.answer break } return person }, {}) // 初始值为空对象 ) } console.log(JSON.stringify(result, null, 2))
这种方式无需手动管理数组的push操作,逻辑更清晰,也更易维护。
内容的提问来源于stack exchange,提问作者martyno
相关产品推荐
相关产品推荐

