JavaScript中reduce处理特定结构对象仅返回最后一个对象的问题
解决Object.reduce只返回最后一个对象的问题
首先咱们得先揪出问题根源:在用reduce的时候,如果没给累加器设置合适的初始值,或者每次迭代时直接替换了累加器(而不是更新它的属性),就会导致最终只留下最后一个被处理的对象。
针对你的myObj结构,我给你两种最常用的解决方案,你可以根据实际需求选:
方案1:保留所有id开头的对象 + 保留j键
如果你想把所有idxxx开头的对象都留在新对象里,同时保留原有的j键,代码可以这么写:
var myObj = { 'id001':{ a:'a', b:'b', c:'c', d:'d', e:'e', f:'f', g:'g', h:'h', i:'i'}, 'id002':{ a:'a', b:'b', c:'c', d:'d', e:'e', f:'f', g:'g', h:'h', i:'i'}, 'id003':{ a:'a', b:'b', c:'c', d:'d', e:'e', f:'f', g:'g', h:'h', i:'i'}, 'j':'j' }; var newObj = Object.keys(myObj).reduce((acc, key) => { // 处理id开头的键,直接添加到累加器对象中 if (key.startsWith('id')) { acc[key] = myObj[key]; } // 单独处理j键,保留原属性 else if (key === 'j') { acc[key] = myObj[key]; } // 关键!一定要返回更新后的累加器,不能直接返回当前对象! return acc; }, {}); // 这里的{}是累加器的初始空对象,绝对不能少! console.log(newObj);
为什么之前会只返回最后一个对象?
很大概率是你犯了这两个错误之一:
- 没给
reduce设置初始值(也就是第二个参数{}),导致第一次迭代时acc是第一个键对应的值,后续迭代不断覆盖它; - 迭代时直接把
acc替换成了myObj[key],比如错误写法:
// 错误示例:每次直接返回当前值,覆盖之前的累加结果 var wrongObj = Object.keys(myObj).reduce((acc, key) => { return myObj[key]; });
方案2:把所有id开头的对象整理成数组(如果需要的话)
如果你想把所有idxxx的对象提取到一个数组里,同时单独保留j键,代码可以这么写:
var newObj = Object.keys(myObj).reduce((acc, key) => { if (key.startsWith('id')) { acc.items.push(myObj[key]); } else if (key === 'j') { acc.j = myObj[key]; } return acc; }, { items: [], j: '' }); // 初始值设置为包含数组和j的结构 console.log(newObj); // 输出:{ items: [id001对象, id002对象, id003对象], j: 'j' }
核心要点总结
- 必须给
reduce设置合适的初始值(比如空对象{}或自定义结构),否则累加器的初始状态会不符合预期; - 每次迭代要更新累加器的属性,而不是直接替换累加器本身,最后一定要返回更新后的累加器。
内容的提问来源于stack exchange,提问作者Francisr
相关产品推荐
相关产品推荐

