如何根据对象键值合并两个对象数组?
问题描述
我想通过相同的id,用另一个对象数组中的项扩展我的对象数组,尝试用array.map实现但结果不符合预期。
第一个数组(原数据):
[ { "objectId": 330, "items": [ { "status": 0, "id": 20, "orderId": 103 }, { "status": 0, "id": 22, "orderId": 120 } ] }, { "objectId": 250, "items": [ { "status": 0, "id": 45, "orderId": 99 }, { "status": 0, "id": 13, "orderId": 100 } ] } ]
第二个数组(扩展数据):
[ { "name": "Toilet", "price": 100, "id": 45 }, { "name": "TV", "price": 800, "id": 20 }, { "name": "Book", "price": 20, "id": 13 } ]
期望的合并结果:
[ { "objectId": 330, "items": [ { "status": 0, "id": 20, "orderId": 103, "values": { "name": "TV", "price": 800, "id": 20 } }, { "status": 0, "id": 22, "orderId": 120, "values": null } ] }, { "objectId": 250, "items": [ { "status": 0, "id": 45, "orderId": 99, "values": { "name": "Toilet", "price": 100, "id": 45 } }, { "status": 0, "id": 13, "orderId": 100, "values": { "name": "Book", "price": 20, "id": 13 } } ] } ]
解决方案
先把扩展数据转换成以id为键的映射对象,后续查找时时间复杂度为O(1),比反复遍历数组效率更高。之后遍历原数组,给每个items项添加匹配的扩展数据:
// 将扩展数据转为id映射,便于快速查找 const valueMap = secondArray.reduce((map, item) => { map[item.id] = item; return map; }, {}); // 处理原数组,合并数据 const mergedArray = firstArray.map(obj => ({ ...obj, items: obj.items.map(item => ({ ...item, values: valueMap[item.id] || null })) }));
代码说明
- 构建映射对象:用
reduce把第二个数组转成{ [id]: 对应对象 }的结构,比如{20: {...TV数据}, 45: {...Toilet数据}},后续可以直接通过id快速取值。 - 遍历原数组:对原数组的每个对象,用扩展运算符保留原有属性,仅修改
items字段。 - 处理items数组:对每个item,保留原有属性的同时,添加
values字段——从映射对象中取对应id的数据,无匹配则设为null。
这样就能得到符合预期的合并结果,且性能优于嵌套使用map+find的方式。
内容的提问来源于stack exchange,提问作者tartalet
相关产品推荐
相关产品推荐

