DEV Community

Nick
Nick

Posted on

Creating an Array of Unique Objects in Javascript

I recently uncovered a nifty trick to be able to create a unique array of objects in Javascript that you should definitely add to your tool belt.

Have you ever found yourself building up some sort of array that contains objects that may contain duplicates? What I mean is ending up with something like this:

const arrayOfObjs = [
  {id: '123', code: 'ABC'},
  {id: '456', code: 'DEF'},
  {id: '123', code: 'ABC'},
  ...
]
Enter fullscreen mode Exit fullscreen mode

So, how can we remove the duplicates here?

In these sorts of situations my instinct is to use lodash, but this can be done with plain old Javascript.

By utilizing the Map constructor and creating a new Map instance, this array can be filtered down to unique values.

const arrayOfObjsMap = new Map(
  arrayOgObjs.map((item) => {
    return [JSON.stringify(item), item];
  }),
);

const uniqueArrayOfObjs = arrayOfObjsMap.values();
Enter fullscreen mode Exit fullscreen mode

This method of removing duplicates from the array takes advantage of the fact that keys in Maps are unique, so the removal of duplicates will inherently be taken care of through the construction of this Map.

The Map constructor can take an iterable (per the MDN docs) which can represent key-value pairs for the Map object. So, by using JSON.stringify() on the iteratees of our array we are able to create a unique string when constructing our Map keys which serves as the unique identifier for our objects. Then by simply calling values() on the new Map instance we are back to having an array of objects but now we have no duplicates.

Hope you find this useful!

Top comments (2)

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

You don't even need to use Map - you could just construct a regular object using Object.fromEntries (normal object keys are also unique):

const uniqueArrayOfObjs = objArr => Object.values(Object.fromEntries(
   objArr.map(item => [JSON.stringify(item), item])
))
Enter fullscreen mode Exit fullscreen mode

One issue with this method is what you consider to be 'the same'. Are these two objects 'the same'? They would be treated as different with the JSON.stringify technique:

const objs = [
   { a: 1, b: 2 },
   { b: 2, a: 1 }
]
Enter fullscreen mode Exit fullscreen mode

One way to possibly fix this would be to sort the keys of the objects in the array to be processed before building the object or map.

Collapse
 
nickcosmo profile image
Nick

Great call out! Indeed the items included in the objects could throw things off. Thanks for the fromEntries method, I was not aware of that one!