Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine multiple JSON objects where key value is the same

I'm trying to combine objects which share the same module key value, i.e. "credit cards". I need to return a single object per unique module with an array of distinct companies. The id and prod keys aren't important.

Here's the object I need to transform:

const data = [
   {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "mortgages", id: "4", company: "EFG", prod: "3"}
]

I need to return something like this:

const result = [
{module: "credit_cards", company: ["ABC", "XYZ", "EFG"]}, 
{module: "mortgages", company: ["EFG"]}
]

So far, I've tried this function:

const result = data.reduce(function(r, e) {
  return Object.keys(e).forEach(function(k) {
    if(!r[k]) r[k] = [].concat(e[k])
    else r[k] = r[k].concat(e[k])
  }), r
}, {})

But it just concatenated all the key/values together...

Any help would be awesome, thanks :)

like image 717
watsbeat Avatar asked May 14 '26 16:05

watsbeat


1 Answers

You can use first Array.reduce() to group the companies by the module key on a Set. On a second step you can use array.Map() over the generated object .entries() to get the final desired result:

const data = [
   {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "mortgages", id: "4", company: "EFG", prod: "3"}
];

let res = data.reduce((acc, {module, company}) =>
{
    acc[module] = acc[module] || new Set();
    acc[module].add(company);
    return acc;
}, {})

res = Object.entries(res).map(
    ([module, companies]) => ({module, company: [...companies]})
);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
like image 175
Shidersz Avatar answered May 17 '26 06:05

Shidersz