How to merge objects by value and change property type?

Viewed 50

I have this array of objects

[ { "value": "1", "hobbies": 'netflix'},{ "value": "1", "hobbies": 'food'} ]

I want to:

  1. Merge objects by value attribute
  2. Change hobbies property to an array
  3. Merge property values

The expected output

[ { "value": "1", "hobbies": ['netflix','food']}]
3 Answers

Using reduce comes in handy here as it helps you iterate over the array and keep an accumulator to store the data in each iteration.

I set the acc to be a JSON object (key-value pairs) where the key is the value attribute and the value is the resulting item with this value.

Along the way, if there is no item with the given key in the acc, we add the object as it is while setting hobbies as an array instead of a string.

Otherwise, if it does contain such an object, we add it's value to the existinghobbies list.

Finally, we take the values of the resulting object which gives the list of grouped objects.:

const arr = [ 
  { "value": "1", "hobbies": 'netflix'},
  { "value": "2", "hobbies": 'reading'},
  { "value": "1", "hobbies": 'food'},
];

const res = Object.values(
  arr.reduce((acc,item) => {
    const { value, hobbies } = item;
    acc[value] = acc[value] 
      ? { ...acc[value], hobbies: [...acc[value].hobbies, item.hobbies] } 
      : { ...item, hobbies: [hobbies] };
    console.log(acc);
    return acc;
  }, {})
);

console.log(res);

You can use a forEach loop to iterate through the array.

var arr = [ { "value": "1", "hobbies": 'netflix'},{ "value": "1", "hobbies": 'food'} ];

var k = {};
var out = [];
arr.forEach(elm => {
  if(typeof(k[elm.value]) == "undefined")
    k[elm.value] = {value:elm.value, hobbies:[]};
  k[elm.value].hobbies.push(elm.hobbies);
});

Object.keys(k).forEach(key => out.push(k[key]));

console.log(out);

You can use Array#reduce with an object to store the result for each value. On each iteration, if the current value does not exist as a key in the accumulator object, we create it and initialize the hobbies property as an empty array. Then, we add the current hobby to the object at that value. After the reduce operation, we use Object.values to get an array of all the resulting values.

const arr = [ { "value": "1", "hobbies": 'netflix'},{ "value": "1", "hobbies": 'food'} ];
const res = Object.values(
    arr.reduce((acc,{value, hobbies})=>
       ((acc[value] = acc[value] || {value, hobbies: []}).hobbies.push(hobbies), acc),
  {}));
console.log(res);

Related