如何对比两个对象数组并补全缺失的type键值对(total设为0)
问题:补全两个对象数组的缺失type项
需求:对比两个包含type和total属性的对象数组,当数组间存在不同的type值时,为两个数组补全对方拥有但自身缺失的type对应的对象,且该对象的total值设为0。
示例输入
let obj1 = [ {"type": "Riesenslalom","total": 2862}, {"type": "Slalom", "total": 362 }, {"type": "Super-G", "total": 579 }]; let obj2 = [ {"type": "Riesenslalom","total": 2218}, {"type": "Slalom","total": 448}, {"type": "Wall", "total": 133 } ];
期望输出
let obj1 = [ {"type": "Riesenslalom","total": 2862}, {"type": "Slalom", "total": 362 }, {"type": "Super-G", "total": 579}, {"type": "Wall", "total": 0 } ]; let obj2 = [ {"type": "Riesenslalom","total": 2218}, {"type": "Slalom","total": 448}, {"type": "Super-G", "total": 0 }, {"type": "Wall", "total": 133 } ];
解决方案
方法1:利用Set收集所有type,遍历补全
核心思路:先提取两个数组中所有type值去重,再遍历所有type为每个数组补全缺失项。
// 提取并去重所有type const allTypes = new Set([...obj1.map(item => item.type), ...obj2.map(item => item.type)]); // 补全obj1 obj1 = [...allTypes].map(type => { const existingItem = obj1.find(item => item.type === type); return existingItem ? existingItem : { type, total: 0 }; }); // 补全obj2 obj2 = [...allTypes].map(type => { const existingItem = obj2.find(item => item.type === type); return existingItem ? existingItem : { type, total: 0 }; });
方法2:用对象映射优化查找效率
如果数组规模较大,find方法的O(n)查找会影响性能,可先将数组转为type为键的映射对象,再快速生成补全后的数组:
// 将数组转为type映射对象,优化查找速度 const obj1Map = Object.fromEntries(obj1.map(item => [item.type, item])); const obj2Map = Object.fromEntries(obj2.map(item => [item.type, item])); // 提取所有type const allTypes = new Set([...Object.keys(obj1Map), ...Object.keys(obj2Map)]); // 生成补全后的obj1 obj1 = [...allTypes].map(type => obj1Map[type] || { type, total: 0 }); // 生成补全后的obj2 obj2 = [...allTypes].map(type => obj2Map[type] || { type, total: 0 });
补充说明
- 两种方法都会保留原数组中已有对象的引用,若需要创建新对象避免引用关联,可改用
{...existingItem}展开原对象 - 最终数组的顺序由
allTypes的遍历顺序决定,若需要保留原数组的type顺序,可以先合并原数组type列表再去重
内容的提问来源于stack exchange,提问作者Leander Costa
相关产品推荐
相关产品推荐

