If you have an array of objects and you want to filter the array to remove duplicate objects but do so based on a provided key/property, this might prove to be a problem you would expect Javascript to address natively. If you are using Lodash then you have many methods at your disposal that can help.
Fortunately, if you are working with ES6 and up, writing some basic Javascript using the filter
and map
functions makes this possible.
The code does a basic filter which is akin to a for..loop where you return true or false to remove or keep the item. We can use the map
method to create a temporary array, then we use the indexOf
method to see if we can find the same object inside of our map. If we do, then we know it is a duplicate.
Nothing overly fancy or complicated here, but undoubtedly useful.
Pretty cool stuff! I just tested out the code, and it works except for undefined property. The function returns the first index in this case. example :
array = [{
greeting: “Hello”,
name : “Aziz”
}, {
greeting: “Hello”,
nickName : “Aziz”
}, {
greeting: “Hello”,
nickName : “test”
}
];
let test = removeDuplicates(array, “fake”);
console.log(test);
function removeDuplicates(myArr, prop) {
return myArr.filter((obj, pos, arr) => {
return arr.map(mapObj =>
mapObj[prop]).indexOf(obj[prop]) === pos;
});
}
// output: [ { greeting: ‘Hello’, name: ‘Aziz’ } ]
Any idea why?
great example !! thanks worked for me π
thanks for the example.
filter and map array methods are standard since ES5.
Thanks for the example, it’s a beautiful implementation
I was testing this out and noticed that it will cause problems if run on an array with values for prop that are already unique. It ends up only returning the first value.
thank you for this. coming from C# down to JS was a bit of a step. really helped me, works like a charm.
You save me, thanks a lot!
Thanks
Thank you! This is super useful.
Hello,
You can use this function:
let test = removeDuplicates(array, “fake”);
console.log(test);
function removeDuplicates(myArr, prop) {
return myArr.filter((obj, pos, arr) => {
if (obj.mvtIdentifier) {
return arr.map(mapObj =>
mapObj[prop]).indexOf(obj[prop]) === pos;
} else {
return arr.push(obj);
}
});
}
Nice article, so much helpful on time.
Thanks a lot!!
Thanks :)))
absolute working bro, thanks.
awesome, thank you very much, you save my life :”>
Thanks for the example, nice tip
I used a variation of this for work – but my team lead said it was an iteration within an iteration, and I should do both operations with one reduce() function. Is this the case? I tried reduce(), but then I have to push to a new array anyway, which is what map() in your example does. Dealing with the output of reduce also makes te code more complex. Thoughts? Do you know if your example is On, O1, etc.?
Hi Dwayne,
Thanks! You’re very good.
It saved our day π
Hi Dwayne,
It’s a great tip, but it is possible to get much better performance, declaring the map before, because it will be the same and you’re creating again in each interaction.
We can do it like that:
function unique2(prop){
const vetP = vet.map( el => el[prop]); // I only need to do that one time;
return vet.filter( (obj, index) => {
return vetP.indexOf(obj[prop]) === index;
})
}
Hi Dwayne,
Itβs a great tip, but it is possible to get much better performance, declaring the map before, because it will be the same and youβre creating again in each interaction.
We can do it like that:
function unique2(vet, prop){
const vetP = vet.map( el => el[prop]); // I only need to do that one time;
return vet.filter( (obj, index) => {
return vetP.indexOf(obj[prop]) === index;
})
}
Thanks a lot!
Thanks, great example !! π
5 years later this post still helps people, thanks! exactly what I needed π