Alex Hunter
Alex Hunter

Reputation: 260

How to merge objects by value and change property type?

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']}]

Upvotes: 2

Views: 91

Answers (3)

Majed Badawi
Majed Badawi

Reputation: 28414

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);

Upvotes: 2

Unmitigated
Unmitigated

Reputation: 89284

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);

Upvotes: 1

Liftoff
Liftoff

Reputation: 25392

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);

Upvotes: 1

Related Questions