You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并同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;
    });
}
代码说明
  1. 构建映射表:将第一个数组中的对象以userId为键存入Map,后续可以用O(1)的时间复杂度查找对应email,提升效率。
  2. 遍历合并:对第二个数组的每个条目,先复制自身避免污染原数据,再把第一个数组中匹配到的字段(如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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:01:18