This question already has an answer here:
-
Combining JavaScript objects in an array with same key value
4 answers
I'm trying combine multiple arrays by a specific key
property. For example, I have
arr1
[{
key: 'A',
items: [{name: 'a item'}]
}, {
key: 'B',
items: [{name: 'b item'}]
}]
arr2
[{
key: 'B',
items: [{name: 'another b item'}, {name: 'more b items'}, {name: 'even more b items'}]
}]
How do I produce the following arr3?
[{
key: 'A',
items: [{name: 'a item'}]
},
{
key: 'B',
items: [{name: 'b item'}, {name: 'another b item'}, {name: 'more b items'}, {name: 'even more b items'}]
}]
May use a hash table like this:
arr1=[{
key: 'A',
items: [{name: 'a item'}]
}, {
key: 'B',
items: [{name: 'b item'}]
}];
arr2=[{
key: 'B',
items: [{name: 'another b item'}, {name: 'more b items'}, {name: 'even more b items'}]
}];
console.log(arr1.concat(arr2).reduce((function(hash){
return function(array,obj){
if(!hash[obj.key])
array.push(hash[obj.key]=obj);
else
hash[obj.key].items.push(...obj.items);
return array;
};
})({}),[]));
Some explanation:
arr1.concat(arr2)//just work with one array as its easier
.reduce(...,[]));//reduce this array to the resulting array
//through
(function(hash){//an IIFE to closure our hash object
...
})({})
//which evaluates to
function(array,obj){//take the resulting array and one object of the input
if(!hash[obj.key])//if we dont have the key yet
array.push(hash[obj.key]=obj);//init the object and add to our result
else
hash[obj.key].items.push(...obj.items);//simply concat the items
return array;
};
Snippet I have that I've used many times for similar. Changed naming for your usecase.
var output = array.reduce(function(o, cur) {
// Get the index of the key-value pair.
var occurs = o.reduce(function(k, item, i) {
return (item.key === cur.key) ? i : k;
}, -1);
// If the name is found,
if (occurs >= 0) {
// append the current value to its list of values.
o[occurs].item = o[occurs].value.concat(cur.items);
// Otherwise,
} else {
// add the current item to o (but make sure the value is an array).
var obj = {key: cur.key, item: [cur.items]};
o = o.concat([obj]);
}
return o;
}, []);