1

Recently, I had to remove duplicates from an array of objects that I retrieved from MongoDB. Here is how I made it work:

let users = [{_id:"abc",name:"Bob"},{_id:"xyz",name:"Al"},{_id:"abc",name:"Bob"}];
let uniqueUsers = [...new Set(users.map(x => JSON.stringify(x)))].map(y => JSON.parse(y));

console.log(users)
console.log(uniqueUsers) //expected output : [{_id:"abc",name:"Bob"},{_id:"xyz",name:"Al"}]

But I am wondering, is it an efficient way of doing it? Can it be done more elegantly? I figured that using some of the new features of ES6 would be a good way. What do you think ?

Edit : Since my objects are MongoDB documents, their ID is unique.

JrmDel
  • 390
  • 1
  • 4
  • 16
  • As the entries are an array of objects, using a set here does not really remove the duplicates, as each object points to a different reference – Sushanth -- May 04 '20 at 17:33
  • @Sushanth-- he's using JSON.stringify, so it will not use reference, but string comparison. – Radu Diță May 04 '20 at 17:33
  • My bad, skipped over `stringify`, but still it is brittle as all the entries should be in the same format. – Sushanth -- May 04 '20 at 17:35
  • 1
    @user2864740 I mostly found old topics on that subject (before ES6) and I wondered if there were new ways that I had not seen that could solve this – JrmDel May 04 '20 at 17:35
  • 1
    Does this answer your question? [How do you performance test JavaScript code?](https://stackoverflow.com/questions/111368/how-do-you-performance-test-javascript-code) – Mohammad Usman May 04 '20 at 17:36
  • Also https://stackoverflow.com/questions/2218999/remove-duplicates-from-an-array-of-objects-in-javascript – Mohammad Usman May 04 '20 at 17:37
  • Does this answer your question? [Remove duplicates from an array of objects in JavaScript](https://stackoverflow.com/questions/2218999/remove-duplicates-from-an-array-of-objects-in-javascript) – BadPiggie May 04 '20 at 17:37
  • 1
    @MohammadUsman No, that does **not** answer the question. Include such as a reference link, not an vote-to-close. – user2864740 May 04 '20 at 17:38
  • 2
    Yes using JSON as the identity of an object is really expensive. There are lots of ways to do it making this question too open ended. – Ruan Mendes May 04 '20 at 17:44

1 Answers1

1

Considering you have _id on each object, is probably easier to get a unique set for those and map them

[...new Set(users.map(user => user._id))].map( id => users.find(user => user._id === id) )

Or you could reduce it based on _id

const reducedUsers = users.reduce( (acc, user) => { 
 acc[user._id] = user
 return acc
}, {} )

Object.values(reducedUsers)
Radu Diță
  • 13,476
  • 2
  • 30
  • 34
  • At first, it seemed to me that you way of filtering by id and then using find() to recreate the whole object was not efficient. Actually, I was wrong, it's the best so far. I've compared using `console.time()` as suggested in a link in comments. Sometimes, even up to **10x** quicker than my original time. Thanks ! – JrmDel May 04 '20 at 18:14
  • 2
    JSON.parse and JSON.stringify are eating a lot of cycles, that's most likely why it takes so long. – Radu Diță May 04 '20 at 18:15