0

I have an array of objects:

var test = [{name: 'lorem', age: 20, color:'red'}, {name: 'lorem', weight: 1, height:5} , {name: 'hello', ipsum : 'dolor'}]

I would like to merge and group them. Expected result is:

var test = [{name: 'lorem', age : 20, color: 'red', weight : 1, height : 5}, {name: 'hello', ipsum : 'dolor'}]

Solution can be in vanilla, lodash or JQuery ...

EDIT: Sorry guys, I forgot to say that it has to be written in ES5

EDIT: I almost rewrote gorak's propostion to ES5. I tried _.clone to avoid using spread opearator but it doesn't work

var r = _.values(_.reduce(test,function (acc, e) {
    acc[e.name] = {...(acc[e.name] || {}), ...e}; // this line is still in ES6
    return acc;
},{}));
  • What happens if there are two of the same property name? – Heretic Monkey Jun 24 '20 at 20:47
  • Does this answer your question? [Merge 2 arrays of objects](https://stackoverflow.com/questions/7146217/merge-2-arrays-of-objects) – Heretic Monkey Jun 24 '20 at 20:48
  • @HereticMonkey> If two proerty are same, property has to be rewritted with the last value. BTW: the link you provide doesn't solve my issue because I'm working with only one array –  Jun 25 '20 at 08:52

3 Answers3

1

You can make use of reduce and take Object.values. Here is a working example:

var test = [{name: 'lorem', age: 20, color:'red'}, {name: 'lorem', weight: 1, height:5} , {name: 'hello', ipsum : 'dolor'}];

var result = Object.values(test.reduce((acc, e)=>{
    acc[e.name] = {...(acc[e.name] || {}), ...e};
    return acc;
},{}));

console.log(result);

Also another approach could be to take Set values(unique names) and then use Object.assign to merge the filtered array. Give this a try:

var test = [{name: 'lorem', age: 20, color:'red'}, {name: 'lorem', weight: 1, height:5} , {name: 'hello', ipsum : 'dolor'}];

var result = [...new Set(test.map(({name})=>name))].map(n=>Object.assign(...test.filter(p=>p.name==n)));

console.log(result);
gorak
  • 5,233
  • 1
  • 7
  • 19
0

You can use below method

var test = [
  { name: 'lorem', age: 20, color: 'red' },
  { name: 'lorem', weight: 1, height: 5 },
  { name: 'hello', ipsum: 'dolor' },
]

const finalResult = test.reduce((result, obj) => {
  if (result[obj.name]) {
    result[obj.name] = {
      ...result[obj.name],
      ...obj,
    }
  } else {
    result[obj.name] = { ...obj }
  }
  return result
}, {})

console.log(Object.values(finalResult))
Nithish
  • 5,393
  • 2
  • 9
  • 24
0

This function will do the trick!

(The name is placed at the bottom of each object, but that doesn't matter)
(pure JS)

function mergeList(list) {
  var temp = {};
  list.forEach(elem => {
    var name = elem.name;
    delete elem.name;
    temp[name] = {
      ...temp[name],
      ...elem
    }
  });
  var merged = [];
  Object.keys(temp).forEach(key => {
    var object = temp[key];
    object.name = key;
    merged.push(object);
  });
  return merged;
}

var test = [{
  name: 'lorem',
  age: 20,
  color: 'red'
}, {
  name: 'lorem',
  weight: 1,
  height: 5
}, {
  name: 'hello',
  ipsum: 'dolor'
}];

console.log(mergeList(test));
Antoni
  • 356
  • 5
  • 17