Skip to content

Combine children where parent keys are the same in a array of objects

I have an array of objects with duplicate parent keys:

[
    {parent1: {'child_id_1': 'value_child_1'}}
    {parent1: {'child_id_1_1': 'value_child_1_1'}}
    {parent2: {'child_id_2_1': 'value_child_2_1'}}
    {parent2: {'child_id_2_2': 'value_child_2_2'}}
    {parent2: {'child_id_2_3': 'value_child_2_3'}}
    ...
]

And I’m looking for this result:

[
    {parent1: {'child_id_1': 'value_child_1'}, {'child_id_1_1': 'value_child_1_1'}}
    {parent2: {'child_id_2_1': 'value_child_2_1'}, {'child_id_2_2': 'value_child_2_2'}, {'child_id_2_3': 'value_child_2_3'}}
]

I’ve tried something similar to this below but it only returns one key pair.

const unique = Array.from(new Set(filteredViews.map(a => a.id)))
   .map(id => {
       return filteredViews.find(a => a.view_name === id)
})

Any help would be greatly appreciated!

Answer

Using Array.prototype.reduce:

const srcArr = [
    {parent1: {'child_id_1': 'value_child_1'}},
    {parent1: {'child_id_1_1': 'value_child_1_1'}},
    {parent2: {'child_id_2_1': 'value_child_2_1'}},
    {parent2: {'child_id_2_2': 'value_child_2_2'}},
    {parent2: {'child_id_2_3': 'value_child_2_3'}},
];

const targetArr = srcArr.reduce((acc, val) => {
  let [key] = Object.keys(val);
  let obj = acc.find(el => key in el);
  if (!obj) acc.push({[key]: [val[key]]});
  else obj[key].push(val[key]);
  return acc;
}, []);

console.log(targetArr);
/* result:
[
  {
    "parent1": [
      {
        "child_id_1": "value_child_1"
      },
      {
        "child_id_1_1": "value_child_1_1"
      }
    ]
  },
  {
    "parent2": [
      {
        "child_id_2_1": "value_child_2_1"
      },
      {
        "child_id_2_2": "value_child_2_2"
      },
      {
        "child_id_2_3": "value_child_2_3"
      }
    ]
  }
]
*/