如何在JavaScript中基于相似属性高效合并两个对象数组?
两个同ID对象数组的高性能合并方案
你遇到的超时问题本质是用了嵌套遍历的写法(比如遍历arr1时,内部再用find/filter遍历arr2匹配id),这种写法时间复杂度是O(n*m),千条级数据会产生百万次级循环操作,开销自然高。只要改成哈希映射的线性时间复杂度写法,哪怕是十万条级数据都不会有性能问题。
原生JS无依赖实现(性能最优)
核心思路是先把其中一个数组转为以id为键的哈希表,后续匹配时直接O(1)复杂度取对应对象合并,全程仅需两次单层遍历,时间复杂度O(n+m)。
// 样例数组修正了原定义里的语法错误 const arr1 = [{id:1, name:'John'}, {id:2, name:'Adam'}] const arr2 = [{id:1, address:'NY', number: 200}, {id:2, address:'LA', number: 300}] // 第一次遍历:把arr2转成id为key的Map映射 const idMap = new Map() for (const item of arr2) { idMap.set(item.id, item) } // 第二次遍历:直接按id取对应项合并 const newArr = arr1.map(item => ({ ...item, ...idMap.get(item.id) }))
注意:不要在遍历arr1时内部写arr2.find(i => i.id === item.id)这类逻辑,这就是你之前超时的根源,find本身会隐式遍历整个arr2,和手写嵌套循环没有区别。
Lodash 内置方法实现
如果项目已经引入了Lodash,可以直接用内置的keyBy方法生成哈希映射,内部实现逻辑和上面的原生写法一致,性能无明显差异:
import _ from 'lodash' const idMap = _.keyBy(arr2, 'id') const newArr = _.map(arr1, item => _.assign({}, item, idMap[item.id]))
如果需要深度合并属性(比如对象里还有嵌套子对象),把_.assign换成_.merge即可。
边界提示:如果两个数组存在id不匹配的缺项情况,上述写法会自动跳过不存在的属性,不会抛错;如果需要保留所有id的项,可以先把两个数组的所有id收集去重后,再基于映射表做合并。
内容的提问来源于stack exchange,提问作者Jam
相关产品推荐
相关产品推荐

