JavaScript如何实现对象数组合并 同key时用后者值覆盖
数组同key值属性覆盖实现方案
核心逻辑分两步:先匹配两个数组中key相同的元素,再用content2的对应属性值覆盖content1的原有值,下面提供两种可直接运行的写法:
写法1:map+find 基础实现(适合小数据量场景)
你之前尝试用map、find组合没成功,大概率是没有正确处理匹配后的值返回,正确写法如下:
const updatedContent1 = content1.map(item => { // 查找content2中key相同的元素 const matched = content2.find(i => i.key === item.key) // 匹配到就覆盖coin属性,没匹配到返回原元素 return matched ? { ...item, coin: matched.coin } : item })
这个写法逻辑直观,但是两个数组长度都很大的时候,每次find都会遍历整个content2,性能较差。
写法2:Map映射优化实现(推荐,性能更好)
提前把content2的key和对应coin值存成映射表,把时间复杂度从O(n*m)降到O(n+m),数据量越大优势越明显:
// 先构建key到coin值的映射 const coinValueMap = new Map() content2.forEach(i => coinValueMap.set(i.key, i.coin)) // 遍历原数组做覆盖 const updatedContent1 = content1.map(item => { return coinValueMap.has(item.key) ? { ...item, coin: coinValueMap.get(item.key) } : item })
直接修改原数组的写法
如果你不需要保留原content1的数据,不需要生成新数组,可以直接遍历赋值,内存开销更小:
content2.forEach(i2 => { const target = content1.find(i1 => i1.key === i2.key) if (target) target.coin = i2.coin })
效果验证:用你给出的测试数据运行上述任意一种写法,得到的content1结果完全符合预期:
[ { key: 1, coin: 0 }, { key: 2, coin: 400 }, { key: 3, coin: 0 } ]
扩展说明
- 如果后续需要覆盖的不只是
coin属性,而是content2同key元素下的所有属性,直接把覆盖逻辑改成return matched ? { ...item, ...matched } : item即可,不需要单独指定属性名 - 如果是在React/Vue框架中修改状态值,不要直接修改原数组,要用生成新数组的写法,避免响应式更新不触发
内容的提问来源于stack exchange,提问作者minsu123
相关产品推荐
相关产品推荐

