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.

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I want to compare whole object. Will uniq work in that case?
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)
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).
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.