1

What is quickest and easiest way to merge two arrays without duplicates in Angular2/Typescript (ES6).

p.s. Arrays contain nested objects.

I know there are lot of answers already there. That's why I'm confused. I tried answers on this, but I couldn't get it working.

Thanks in advance.

Community
  • 1
  • 1
Paresh Nagore
  • 336
  • 2
  • 7
  • 23

2 Answers2

7

That's not related to angular2/typescript, my answer works with ES6.

Use uniq function from lodash (https://lodash.com/docs/4.17.4#uniq) on items from your sources array like this:

const arrA = [1, 2, 3, 4];
const arrB = [3, 4, 5, 6];
const arr = _.uniq([...arrA, ...arrB])
// [1, 2, 3, 4, 5, 6]

And for nested object, use uniqBy (https://lodash.com/docs/4.17.4#uniqBy) or uniqWith.

const arrA = [{id: 1, n: 'e'}, {id: 2, n: 'z'}];
const arrB = [{id: 2, n: 'z'}, {id: 3, n: 'c'}];
const arr = _.uniqBy([...arrA, ...arrB], 'id')
// [{id: 1, n: 'e'}, {id: 2, n: 'z'}, {id: 3, n: 'c'}]

But you need a unique identifier (id here) to know when duplicates.

[EDIT] In case, you don't have a unique identifier and want to use whole objects to deduplicate, you can do it like this:

const arrA = [{a: 'a'}, {b: 'b'}];
const arrB = [{b: 'b'}, {c: 'c'}];
const arr = _.uniqBy([...arrA, ...arrB], JSON.stringify)
// [{a: 'a'}, {b: 'b'}, {c: 'c'}]

It will stringify all your object to check if same string values, so remember it could be costly on huge objects/array. That's a better practise to have a unique identifier.

bertrandg
  • 3,147
  • 2
  • 27
  • 35
  • I want to compare whole object. Will _uniq_ work in that case? – Paresh Nagore May 09 '17 at 15:14
  • Problem here is I can have same _id_, but different _n_. In that case its not duplicate, its distinct. Can I have multiple comparators (e.g. _id_ as well as _n_) – Paresh Nagore May 09 '17 at 15:23
  • In that case the JSON.stringify example will do the job. But if you want to compare by two properties, a custom method would be required. Or you could just run the uniq method twice or more(less efficient). – enf0rcer May 09 '17 at 15:33
1

If you use typescript, you can go like this:

const a = [1, 2, 3];
const b = [2, 3, 4, 5];

result = a.concat(b.filter(x => a.every(y => y !== x))); //[1, 2, 3, 4, 5];

With b.filter(x => a.every(y => y !== x)) you are filtering out the duplicates. If you need this for multiple arrays to be concatenated, you'll need to make a function where you will loop the arrays but again with the same approach as above.

function mergeArraysWithoutDuplicates(arrays: any[]){
  var result = [];

  for(const array in arrays){

    result = result.concat(array.filter(x => result.every(y => y !== x));

  }
    return result;
}

The code is not tested, but should be something like this, depends on the needs. As a result the function will return new array without duplicates.

Pnctovski
  • 565
  • 1
  • 9
  • 21