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

基于相同ID合并对象数组:两种方案的性能对比及优化咨询

合并两个含唯一ID对象数组的方案对比与性能分析

需求明确

给定两个数组arr1和arr2,每个元素都是带唯一id属性的对象,需要将两数组中id相同的对象合并(后序对象属性按需覆盖前序),最终得到合并后的数组。

两种现有方案的代码实现

方案1:map + find

const mergedArr1 = arr1.map(item1 => {
  const matchedItem = arr2.find(item2 => item2.id === item1.id);
  return { ...item1, ...matchedItem };
});

遍历arr1的每个元素,再在arr2中逐个查找匹配id的元素,完成合并。

方案2:先转ID映射表再map

先实现arrayToMapById工具函数:

function arrayToMapById(arr) {
  return arr.reduce((map, item) => {
    map[item.id] = item;
    return map;
  }, {});
}

// 合并逻辑
const arr2IdMap = arrayToMapById(arr2);
const mergedArr2 = arr1.map(item1 => ({
  ...item1,
  ...arr2IdMap[item1.id]
}));

先将arr2转换为以id为键的对象映射表,再遍历arr1直接通过键值对快速匹配合并。

性能差异对比

方案1的时间复杂度为O(n*m):map遍历arr1(n次),每次map循环里的find又要遍历arr2(最多m次),总操作次数是两者的乘积。

方案2的时间复杂度为O(n + m):转映射表只需遍历arr2一次(m次),遍历arr1合并时的键取值是O(1)的哈希查找,总操作次数是两者的和。

  • 当数组规模较小时(几百条以内),浏览器引擎对数组方法的优化会让二者性能差异难以感知;
  • 当数组规模达到几千甚至上万条时,方案2的优势会指数级放大:比如arr1和arr2各有10000条数据,方案1需执行1亿次操作,方案2仅需2万次,性能差距非常显著。

更优的合并方式

如果需要双向合并(即保留arr1所有元素的同时,添加arr2中arr1没有的元素),可以基于映射表进一步优化:

function mergeArraysBidirectionally(arr1, arr2) {
  const mergedMap = arrayToMapById(arr1);
  // 遍历arr2,覆盖已有元素或添加新元素
  arr2.forEach(item => {
    mergedMap[item.id] = { ...mergedMap[item.id], ...item };
  });
  // 将映射表转回数组
  return Object.values(mergedMap);
}

这种方式依然保持O(n + m)的时间复杂度,比分开处理再拼接的效率更高。

另外,如果id是Symbol等特殊类型,用ES6的Map代替普通对象做映射兼容性更好:

function arrayToMapById(arr) {
  return arr.reduce((map, item) => {
    map.set(item.id, item);
    return map;
  }, new Map());
}

// 合并逻辑
const arr2IdMap = arrayToMapById(arr2);
const mergedArr = arr1.map(item1 => ({
  ...item1,
  ...arr2IdMap.get(item1.id)
}));

总结

  • 小规模数据下,两种方案性能差异可忽略;数据量越大,方案2的性能优势越明显;
  • 基于映射表(对象或Map)的方式是按唯一键合并场景的最优解,时间复杂度更低;
  • 若需双向合并,基于映射表的全量合并方式是最高效的选择。

内容的提问来源于stack exchange,提问作者greenlihui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 22:55:27