1

I have an array as below:

original = [
{
 id:1,
 value1 : 500
},
{
 id:1,
 value2 : 600
},
{
 id:2,
 value1 : 700
},
{
 id:3,
 value2 : 750
}
];

I want to merge the duplicate objects in the above array and want the final output array as below:

finalArr = [
 {
  id:1,
  value1:500,
  value2:600
},
{
 id:2,
 value1:700,
 value2:null
},
{
 id: 3,
 value1: null,
 value2:750
}
];

How can I achive this using JavaScript or TypeScript?

  • 3
    Possible duplicate of [Merge duplicate objects in array of objects](https://stackoverflow.com/questions/30025965/merge-duplicate-objects-in-array-of-objects) – Tatenda Zifudzi Feb 21 '19 at 14:39

4 Answers4

3

You can use a reduce, map combination

const original = [
    {
        id:1,
        value1 : 500
    },
    {
        id:1,
        value2 : 600
    },
    {
        id:2,
        value1 : 700
    },
    {
        id:3,
        value2 : 750
    }
];

const res = [...original.reduce(
    (a, b) => a.set(b.id, Object.assign((a.get(b.id) || {value2: null, value1: null, id: null}), b)),
    new Map
).values()];

console.log(res);
baao
  • 71,625
  • 17
  • 143
  • 203
1

you can use plain forEach,

let result = [];
original.forEach(elem => {
  let match = result.find(r => r.id === elem.id);
  if(match) {
    Object.assign(match, elem);
  } else {
    result.push(elem);
  }
});
ABOS
  • 3,723
  • 3
  • 17
  • 23
0

You can use lodash uniq or uniqBy function

original = _.uniq(original);

or

original = _.uniqBy(original, 'id');

Otherwise, you can use reduce to check

let original = [
    {
        id: 1,
        value1: 500
    },
    {
        id: 1,
        value2: 600
    },
    {
        id: 2,
        value1: 700
    },
    {
        id: 3,
        value2: 750
    }
];

original = original.reduce((sum, val) => {
    for (let i in sum) {
        if (sum[i].id === val.id) {
            return sum;
        }
    }
    sum.push(val);
    return sum;
}, []);
Nguyen Phong Thien
  • 3,237
  • 1
  • 15
  • 36
0

You could take a Map and collect all object with the same id and get then only the values of the map as result.

var original = [{ id: 1, value1: 500 }, { id: 1, value2: 600 }, { id: 2, value1: 700 }, { id: 3, value2: 750 }],
    template = { id: null, value1: null, value2: null },
    result = Array.from(
        original
            .reduce(
                (m, o) => m.set(o.id, Object.assign({}, m.get(o.id) || template, o)),
                new Map
            )
            .values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392