Appearance
2722. 根据 ID 合并两个数组
ts
/**
* 使用reduce结合map进行映射合并
*/
var join = function (arr1, arr2) {
const idMap = [...arr1, ...arr2].reduce((pre, cur) => {
const mapItem = pre[cur.id]
pre[cur.id] = mapItem ? { ...mapItem, ...cur } : cur
return pre
}, {})
return Object.values(idMap)
}合并语义
这题本质上是在做一个简化版的按 id 合并:以 id 为键合并两个对象数组,同 id 时,arr2 的属性覆盖 arr1 的同名属性。
核心点在于覆盖策略:{ ...mapItem, ...cur } 保证后出现的(arr2)覆盖先出现的(arr1),也就是把第二个数组视为更新版本。
实现细节
实现上先把两个数组拼接起来,再 reduce 到以 id 为 key 的对象中。这样 arr1 的元素先入 map,arr2 的再入,通过展开运算符自然完成覆盖。
Object.values(idMap) 返回最终数组。因为对象的 key 是 id(数字),values 的顺序在某些引擎里会受到 key 迭代规则影响。这里 id 是数字,V8 中数字 key 会按数值大小迭代,结果可能和原始输入顺序不同。如果需要严格保留 arr1 的顺序,就要在 reduce 时额外记录一个 order 列表配合输出。
时间复杂度
O(N + M),N 和 M 分别是两个数组的长度。拼接 + 单次遍历 + values 提取。
