2

Given these two arrays:

const array1 = [
                {"id": 1, "color": "black"},
                {"id": 2, "color": "white"},
                {"id": 3, "color": "orange"}
               ];

const array2 = [
                {"id": 2, "color": "white"},
                {"id": 4, "color": "purple"}
               ];

How could I remove the duplicates from the first array if found in the second, i.e. the result would be:

const filtered = [
                  {"id": 1, "color": "black"},
                  {"id": 3, "color": "orange"}
                 ];

My code:

const filtered = array1.map(i => array2.filter(j => i["id"] !== j["id"]))

but it doesn't seem to work

3
  • 1
    Possible duplicate of How to filter an array from all elements of another array Commented Sep 17, 2019 at 16:00
  • Are duplicates considered by the id property, or by the combination of properties? For example, what would your expected behavior be if array2 contained { "id": 3, "color": "blue" } Commented Sep 17, 2019 at 16:03
  • @AndrewLohr related, but not an exact duplicate. I'm sure there is one, but the answers for that one rely on the ability to compare elements of the array by value (rather than properties of each element). Commented Sep 17, 2019 at 16:10

4 Answers 4

3

To make your code work you can use filter and every

const array1 = [ {"id": 1, "color": "black"},{"id": 2, "color": "white"},{"id": 3, "color": "orange"}];
const array2 = [{"id": 2, "color": "white"},{"id": 4, "color": "purple"}];

const filtered = array1.filter(i => array2.every(j => i["id"] !== j["id"]))

console.log(filtered)

You can use Map and filter

const array1 = [ {"id": 1, "color": "black"},{"id": 2, "color": "white"},{"id": 3, "color": "orange"}];
const array2 = [{"id": 2, "color": "white"},{"id": 4, "color": "purple"}];

let mapper = new Map(array2.map(v=> [v.id,v]))

const final = array1.filter(({id})=> !mapper.has(id))

console.log(final)

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

Comments

0

If you want duplicates removed based on only 'id', you can do so using Array.filter() and Array.find() or Array.some() -

const filtered = array1.filter(x => !array2.find( y => y.id===x.id));

OR

const filtered = array1.filter(x => !array2.some( y => y.id===x.id));

Check this JS Bin to play around.

Comments

0

We can use Array.prototype.filter to filter the first array. The filter condition can be constructed by various means having different time complexities:

  1. Linear time by using the Array.prototype.findIndex which will check if the current object is included in the second array:

const array1 = [{"id": 1, "color": "black"}, {"id": 2, "color": "white"}, {"id": 3, "color": "orange"}];
const array2 = [{"id": 2, "color": "white"}, {"id": 4, "color": "purple"}];

function filterArray(array1, array2,){
  return array1.filter( ({id}) => array2.findIndex((o) => id === o.id ) < 0);
}
console.log(filterArray(array1, array2));

  1. Or this can also be done efficiently by using a Set which has a constant time lookup:

const array1 = [{"id": 1, "color": "black"}, {"id": 2, "color": "white"}, {"id": 3, "color": "orange"}];
const array2 = [{"id": 2, "color": "white"}, {"id": 4, "color": "purple"}];

function filterArrayUsingSet(array1, array2){
  const lookup = new Set(array2.map(({id})  => id));
  return array1.filter( ({id}) => !lookup.has(id) );
}

console.log(filterArrayUsingSet(array1, array2));

  1. Even a Object literal can be used as a key lookup table, where the key will be the ids of array2 this will also be constant time lookup:

const array1 = [{"id": 1, "color": "black"}, {"id": 2, "color": "white"}, {"id": 3, "color": "orange"}];
const array2 = [{"id": 2, "color": "white"}, {"id": 4, "color": "purple"}];

function filterArrayUsingSet(array1, array2){
  const lookup = array2.reduce((acc, {id}) => {acc[id] = id; return acc}, {});
  return array1.filter( ({id}) => !(id in lookup));
}

console.log(filterArrayUsingSet(array1, array2));

Comments

0

If you want to filter array based on any key-value match is found in second array, a solution using forEach and every:

function filterArray(arr1, arr2) {
    let filterArr = [];
    arr1.forEach(item => 
       arr2.every( val => val.id !== item.id && val.color !== item.color) && filterArr.push(item));

    return filterArr;
}

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.