DEV Community

Andrew McKeever
Andrew McKeever

Posted on • Updated on

The JavaScript Set Object

While doing some work the other day, I had a bit of a problem and learned of something I found quite useful, so I thought "Eh what the hell, why not create a post about this?

My team has integrated a WYSIWYG (btw...this apparently stands for What You See Is What You Get, three years in this industry I just now learned this)
into our React application's backend to create posts. These posts have two columns, which can return either markdown, buttons or assets (images and videos). This data gets returned from our GraphQl API as an array of two items, something like this

Array [Object{type: "text"}, Object{type: "asset"}]

Now, these two bits of data will get wrapped into a component with a two-column layout and based on its type (eg: text, asset or button) we render a different component.

So... what's the problem?

In our WYSIWIG editor, any text written inside our first column that overflows maximum word length, the text wraps into our second column, giving our data back a {type: "text"} field. Well, if you're familiar at all with React, to return markdown we use the dangerouslySetInnerHTML prop on our element and pass in our markdown data.

So if we use Array.filter() method to render the appropriate <Image />, <Text /> or <Button /> component, if the Array contains two objects with the text type, I'll end up rendering the markdown twice...obviously not desired.

So just like, remove duplicates from your array dude?

So I need to remove any duplicates from my posts array, which is simple enough to do. We could first use Array.Map() over our posts array to to get each post's type and then use the Array.filter() method to compare the previous item to the current item, giving us a new array that we could then test to the original array to make sure we've got our intended result.

let postTypes = posts.map({post} => post);
let filteredPosts = postTypes.filter((type, i) => types.indexOf(type) === i));

There's nothing at all wrong here with this code. It's fairly simple to reason about, we're not doing any data mutation and we're keeping out side effects from our map. However, there's an even simpler way to return a unique list of Objects (well, any primitive actually) in JavaScript... the Set object.

What is the Set Object?

Set is an object that can store any type of JavaScript primitive (think booleans, strings, numbers here), but it will only store unique primitives. Wait... what??? That's awesome! Yeah, my fellow developer, yeah.

Instead of using the filter method, all we have to do is pass our postTypes array into the Set object and wrap it into an array.

let filteredPosts = [... new Set(postTypes)];

and BAM! a whole new array with its duplicates removed. But, that's not all folks! The Set object also comes with some handy as hell methods to it as well like add() and includes()to add or find objects in your set.

I recommend taking a look at the Mozilla Set documentation at all the cool methods you have at your disposal with Set.

Top comments (2)

Collapse
 
chiangs profile image
Stephen Chiang

I just recently used Set to get all the values of a categories property of a list of objects then took out all the unique ones and used that to create a list to populate a drop-down filter input element.

Worked like a charm!

Collapse
 
keevcodes profile image
Andrew McKeever

Nice work! Creative way to get a solution!