8

I have the following two Javascript arrays:

const array1 = [{ id: 1}, { id: 2 }, { id: 3 }, { id: 4}];
const array2 = [{ id: 1}, { id: 3 }];

I now want a new array array3 that contains only the objects that aren't already in array2, so:

const array3 = [{ id: 2}, { id: 4 }];

I have tried the following but it returns all objects, and when I changed the condition to === it returns the objects of array2.

const array3 = array1.filter(entry1 => {
  return array2.some(entry2 => entry1.id !== entry2.id);
});

Any idea? ES6 welcome

mxmtsk
  • 4,285
  • 6
  • 22
  • 47

2 Answers2

20

You could reverse the comparison (equal instead of unqual) and return the negated result of some.

const
    array1 = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }],
    array2 = [{ id: 1 }, { id: 3 }],
    array3 = array1.filter(entry1 => !array2.some(entry2 => entry1.id === entry2.id));
    //                               ^                                ^^^

console.log(array3);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • if your condition is a direct comparison, you can instead use [`array.includes()`](https://stackoverflow.com/a/68230395/6908282). Additional Reference: [`.includes()` vs `.some()`](https://stackoverflow.com/a/64946579/6908282) – Gangula Sep 02 '22 at 10:03
1

Nina's answer is a good start but will miss any unique elements in array 2. This extends her answer to get the unique elements from each array and then combine them:

const
    array1 = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }],
    array2 = [{ id: 1 }, { id: 3 }, { id: 5 }],
    array3 = array1.filter(entry1 => !array2.some(entry2 => entry1.id === entry2.id)),
    array4 = array2.filter(entry1 => !array1.some(entry2 => entry1.id === entry2.id)),
    array5 = array3.concat(array4);

console.log(array5);
JeKo
  • 59
  • 2