如何将同一年份的JavaScript数组对象合并为单个对象?
合并相同
makeYear的JavaScript对象数组 问题背景
现有如下结构的JavaScript对象数组:
[ { makeYear: 2019, company: 'Mazda', fleet: '900' }, { makeYear: 2019, company: 'Mercedes', fleet: '500' }, { makeYear: 2020, company: 'Honda', fleet: '390' }, // 更多对象 ]
需要将相同makeYear的条目合并为单个对象,目标结构如下:
[ { makeYear: 2019, Mazda: 900, Mercedes: 500, // 该年份下的其他公司 }, { makeYear: 2020, Honda: 390, // 该年份下的其他公司 } ];
尝试了以下代码但未达到预期效果:
const mergeObjs = input.reduce((res, item) => { if (!item.makeYear) return res; res[item.makeYear] = item; return res; }, {}); const merged = input.filter(item => item.makeYear).map(item => { return {...item, ...(mergeObjs[item.makeYear] || {})} });
解决方案
基础实现(直观易懂)
通过一次reduce遍历即可完成合并,核心逻辑是在累加器数组中维护各年份的条目,遇到同一年份时追加公司数据:
const mergedArray = input.reduce((acc, current) => { if (!current.makeYear) return acc; const existingEntry = acc.find(entry => entry.makeYear === current.makeYear); if (existingEntry) { // 已有该年份条目,添加公司及 fleet(转换为数字类型) existingEntry[current.company] = Number(current.fleet); } else { // 无该年份条目,创建新条目并入数组 acc.push({ makeYear: current.makeYear, [current.company]: Number(current.fleet) }); } return acc; }, []);
高性能实现(适合大数据量)
如果数组规模较大,find方法的循环查找会带来性能损耗,可改用对象作为中间映射表,最后将映射值转为数组:
// 用对象做中间映射,快速定位年份条目 const yearMap = input.reduce((map, current) => { if (!current.makeYear) return map; const year = current.makeYear; // 初始化年份条目(若不存在) if (!map[year]) { map[year] = { makeYear: year }; } // 添加当前公司的 fleet 数据 map[year][current.company] = Number(current.fleet); return map; }, {}); // 将映射对象的值转为目标数组 const mergedArray = Object.values(yearMap);
关键说明
- 两个方案都处理了
makeYear不存在的情况,直接跳过无效条目 - 将
fleet的字符串值转为数字类型,符合目标结构的数值要求 - 高性能方案利用对象键的O(1)查找特性,避免了数组遍历查找,数据量越大优势越明显
内容的提问来源于stack exchange,提问作者boomchickawawa
相关产品推荐
相关产品推荐

