如何基于相同ID合并两个对象数组并移除非匹配项?
合并两个对象数组中ID匹配的项并移除无匹配项
问题场景
现有两个对象数组,需要合并其中ID相同的项,同时移除没有匹配ID的项:
Array 1:
let arr1 = [ { id: "123", name: "John" }, { id: "345", name: "Sara" }, { id: "542", name: "Jack" }, ]
Array 2:
let arr2 = [ { id: "123", phone: "021456" }, { id: "345", phone: "0911256" } ]
期望结果:
let arr3 = [ { id: "123", phone: "021456", name: "John" }, { id: "345", phone: "0911256", name: "Sara" } ]
你的代码问题
你当前用的map方法是按数组索引位置合并项,而非根据id匹配:
let arr3 = arr1.map((item, i) => Object.assign({}, item, arr2[i]));
这会导致:
- 前两项因为索引对应且
id碰巧一致,合并结果看似正常 - 第三项由于
arr2[2]不存在(undefined),直接保留了arr1中id:542的项,不符合需求
正确解决方案
核心思路是先把其中一个数组转成以id为键的映射对象,实现O(1)的查找效率,再过滤+合并匹配项:
// 将arr2转换为id映射,方便快速查找 const arr2IdMap = arr2.reduce((map, item) => { map[item.id] = item; return map; }, {}); // 过滤arr1中存在匹配id的项,并合并属性 const arr3 = arr1 .filter(item => arr2IdMap.hasOwnProperty(item.id)) .map(item => ({ ...item, ...arr2IdMap[item.id] })); console.log(arr3);
代码说明
reduce构建映射:把arr2转换成{ "123": {...}, "345": {...} }的结构,后续查找匹配项时无需遍历整个数组,性能更优filter过滤无匹配项:只保留arr1中id存在于映射中的项map合并属性:用扩展运算符...合并两个对象的属性(如果有重复属性,arr2的属性会覆盖arr1的,可根据需求调整顺序)
补充:双向匹配场景
如果需要保留两个数组中都存在id的项(而非仅从arr1筛选),可以调整为:
const arr1IdMap = arr1.reduce((map, item) => { map[item.id] = item; return map; }, {}); const arr3 = arr2 .filter(item => arr1IdMap.hasOwnProperty(item.id)) .map(item => ({ ...item, ...arr1IdMap[item.id] }));
内容的提问来源于stack exchange,提问作者Elham Bagheri
相关产品推荐
相关产品推荐

