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'},
...
]
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();
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)
You don't even need to use
Map
- you could just construct a regular object usingObject.fromEntries
(normal object keys are also unique):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: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.
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!