i have the following arrays
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}},
]
reduced array based on key
should look like this:
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}},
]
first i tried to merge the two arrays using const mergedArray = [...array1, ...array2]
now i want to check for key duplicates. for example, if there is key1 in both array1 and array2, remove the duplicates then combine the values of that key.
this is what i have tried but it is only iterating through a.key
only:
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);
As you confirmed the key
inner property is commonly shared by the four "a", "b", "c", "d" objects in an outer object, the a.key
value can be used to identify which outer objects should merge.
You could group all objects (irrespective of whether they occur in array1
or array2
) by that a.key
, and then aggregate objects that occur in the same group. Both of these actions can be accomplished with a reduce
call:
const aggregate = (objects) =>
objects.reduce((x, y) => ({
a: { key: x.a.key, value: x.a.value + y.a.value },
b: { key: x.b.key, value: x.b.value + y.b.value },
c: { key: x.c.key, value: x.c.value + y.c.value },
d: { key: x.d.key, value: x.d.value + y.d.value },
}));
const merge = (array1, array2) =>
Object.values(array1.concat(array2).reduce((acc, obj) => {
(acc[obj.a.key] ??= []).push(obj);
return acc;
}, {})).map(aggregate);
const 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}},
];
const 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}},
]
console.log(merge(array1, array2));