合并嵌套对象数组并基于key去重累加value的实现问题
合并嵌套对象数组并按key累加对应属性的value
我有以下两个嵌套对象数组:
array1 = [ {a:{key:1 , value: 10} , b:{key:1 , value:12} , c:{key:1 , value: 5} , d:{key:1 , value:2}}, {a:{key:2 , value: 10} , b:{key:2 , value:12} , c:{key:2 , value: 5} , d:{key:2 , value:2}}, {a:{key:3 , value: 10} , b:{key:3 , value:12} , c:{key:3 , value: 5} , d:{key:3 , value:2}}, ]
array2 = [ {a:{key:1 , value: 10} , b:{key:1 , value:12} , c:{key:1 , value: 5} , d:{key:1 , value:2}}, {a:{key:2 , value: 10} , b:{key:2 , value:12} , c:{key:2 , value: 5} , d:{key:2 , value:2}}, {a:{key:4 , value: 10} , b:{key:4 , value:12} , c:{key:4 , value: 5} , d:{key:4 , value:2}}, ]
基于key合并去重后的目标数组应为:
combinedArray= [ {a:{key:1 , value: 20} , b:{key:1 , value:24} , c:{key:1 , value: 10} , d:{key:1 , value:4}}, {a:{key:2 , value: 20} , b:{key:2 , value:24} , c:{key:2 , value: 10} , d:{key:2 , value:4}}, {a:{key:3 , value: 10} , b:{key:3 , value:12} , c:{key:3 , value: 5} , d:{key:3 , value:2}}, {a:{key:4 , value: 10} , b:{key:4 , value:12} , c:{key:4 , value: 5} , d:{key:4 , value:2}}, ]
我已经通过const mergedArray = [...array1, ...array2]合并了两个数组,但需要检查key重复项,若存在相同key则合并对应属性的value。我尝试的kdeAdder函数仅遍历a.key,无法实现需求:
function kdeAdder(param) { const array = [param.a] let tempHistory = []; for(let x=0;x<array.length;x++){ array[x].forEach((item)=>{ let noMatch = true; if(tempHistory.length > 0) { tempHistory.forEach((tempItem, i)=>{ if(item.key === tempItem.key) { tempHistory[i].value += item.value; noMatch = !noMatch; } }); } return (noMatch) ? tempHistory.push(item) : null; }); } return tempHistory; } kdeAdder(mergedArray);
正确实现方法
核心思路是用一个对象作为映射表,以每个元素的key(每个元素的a/b/c/d的key一致,取任意一个即可)作为键,存储已处理的元素。遍历合并后的数组时,若key已存在则累加对应属性的value;若不存在则直接存入映射表,最后将映射表的值转换为数组即可。
function mergeAndSumArrays(arr1, arr2) { const merged = [...arr1, ...arr2]; const map = {}; merged.forEach(item => { // 获取当前元素的唯一key标识 const key = item.a.key; if (map[key]) { // 已存在该key,累加各属性的value map[key].a.value += item.a.value; map[key].b.value += item.b.value; map[key].c.value += item.c.value; map[key].d.value += item.d.value; } else { // 不存在则存入map,深拷贝避免修改原数组对象 map[key] = { a: {...item.a}, b: {...item.b}, c: {...item.c}, d: {...item.d} }; } }); // 将映射表的值转换为目标数组返回 return Object.values(map); } // 使用示例 const combinedArray = mergeAndSumArrays(array1, array2); console.log(combinedArray);
说明
- 映射表
map的作用是快速查找已存在的key,避免嵌套循环,时间复杂度为O(n),效率更高。 - 采用对象浅拷贝(
{...item.a})是为了防止修改原数组中的对象,保证数据独立性。 - 由于每个元素的
a/b/c/d的key完全一致,所以直接取item.a.key作为唯一标识即可。
内容的提问来源于stack exchange,提问作者xtyy
相关产品推荐
相关产品推荐

