如何合并同Key的JavaScript对象并保留匹配Key的重复值
问题分析
原merge函数的核心问题是用obj[b[key]]作为唯一容器存储相同key的对象,导致同一key对应的多个条目被合并覆盖,最终丢失重复的条目。你的需求是保留第二个数组的所有条目,同时为每个条目补充第一个数组中对应userId的email字段,而非合并相同userId的条目。
解决方案
换一种思路:先把第一个数组转换成userId到email的映射表,再遍历第二个数组的每个元素,为每个元素添加对应的email字段,直接生成目标数组。
修改后的代码如下:
function mergeWithDuplicates(arr1, arr2, key) { // 构建key到对应数据的映射表,快速匹配userId对应的email const keyMap = new Map(); arr1.forEach(item => { keyMap.set(item[key], item); }); // 遍历第二个数组,为每个条目补充对应字段 return arr2.map(item => { // 复制当前条目,避免修改原数据 const mergedItem = {...item}; // 取出匹配的对象并合并字段 const matchedData = keyMap.get(item[key]); if (matchedData) { Object.assign(mergedItem, matchedData); } return mergedItem; }); }
代码说明
- 构建映射表:将第一个数组中的对象以
userId为键存入Map,后续可以用O(1)的时间复杂度查找对应email,提升效率。 - 遍历合并:对第二个数组的每个条目,先复制自身避免污染原数据,再把第一个数组中匹配到的字段(如email)合并进去,最终返回包含所有原条目且补充了对应字段的新数组。
测试验证
用你的测试数据调用函数:
const obj1 = [ {"userId":"1", "email":"email1@gmail.com"}, {"userId":"2", "email":"email2@gmail.com"} ]; const obj2 = [ {"id":"1abc", "listingId":"4def", "userId":"2"}, {"id":"2abc", "listingId":"2def", "userId":"1"}, {"id":"3abc", "listingId":"3def", "userId":"2"} ]; const result = mergeWithDuplicates(obj1, obj2, 'userId'); console.log(result);
输出将完全符合你的期望:
[ {"id":"1abc", "listingId":"4def", "userId":"2", "email":"email2@gmail.com"}, {"id":"2abc", "listingId":"2def", "userId":"1", "email":"email1@gmail.com"}, {"id":"3abc", "listingId":"3def", "userId":"2", "email":"email2@gmail.com"} ]
内容的提问来源于stack exchange,提问作者Donzo
相关产品推荐
相关产品推荐

