Reputation: 97
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
Upvotes: 2
Views: 1361
Reputation: 37757
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)
Upvotes: 3
Reputation: 1
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;
}
Upvotes: 0
Reputation: 16908
We can use Array.prototype.filter
to filter the first array. The filter condition can be constructed by various means having different time complexities:
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));
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));
id
s 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));
Upvotes: 0
Reputation: 6894
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.
Upvotes: 0