Introduction
Sets are another collection option that we have available to us in JS. Sets work very similar to Arrays. The difference between the two is that values in a Set must be unique.
Example
const myArray = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4] // This is just fine
But if we create a Set from this array...
const myArray = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4] // This is just fine
const mySet = new Set(myArray) // mySet = [1, 2, 3, 4]
Since a Set will only hold unique values, we only get one instance of each number.
Working with Sets
Sets are great for collections you need to keep unique values in. For example, all of the keys in a Map need to be unique. So if you get a collection of keys from a Map, what you're getting back is a Set.
Let's take a look at making a new Set with a playing card example:
const suits = new Set(['♤', '♡', '♧', '♢']) // Spades, Hearts, Clubs, Diamonds
const vals = new Set(['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'])
const deck = new Set()
for (let suit of suits) {
for (let val of vals) {
deck.add(`${val}${suit}`)
}
}
This gives us a full deck of cards! What's nice about using a Set here is that we can be sure that every value we get is unique. Which, after all, is what you need for a reliable deck of cards.
We can now make some assertions on this set and know we're dealing with unique values. Let's make sure this deck has the Ace of Spades:
deck.has('A♤') // returns true
Removing Values
Let's say we want to deal a 5 card poker hand. Picking 5 random cards isn't too difficult a task, but the trick is that we want to make sure we can't deal the same card twice. How can we pull that off?
const suits = new Set(['♤', '♡', '♧', '♢']) // Spades, Hearts, Clubs, Diamonds
const vals = new Set(['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'])
const deck = new Set()
for (let suit of suits) {
for (let val of vals) {
deck.add(`${val}${suit}`)
}
}
const hand = new Set()
for (let i = 0; i < 5; i++) {
const randomIndex = Math.floor(Math.random() * deck.size)
const card = [...deck][randomIndex]
hand.add(card)
deck.delete(card)
}
console.log(hand)
Try running that code in your browsers console. It works!
Let's step through what we're doing here though. First, we're setting up a loop that will run 5 times. For each iteration we're choosing a random index in our Set and using it to pick a random value in our Set and assigning it to card
.
What is
[...deck][randomIndex]
doing?
Good question. [...deck]
is making an Array out of our Set so that we can select a value by an index. Adding [randomIndex]
to the end actual selects the value at the index we generate.
Then, we're adding the selected card to our hand
Set.
Finally, we're removing that card from our deck
Set.
Other Set Methods
Method | Result |
---|---|
clear() |
Removes all values from the Set |
entries() |
Returns an iterator with key/value pairs of indices and the actual Set values |
forEach() |
Accepts a callback that will run for every value in the Set |
has(value) |
Returns a Boolean value reflecting whether the Set contains the value |
Conclusion
Sets are a really useful collection due to their ability to store unique values. Familiarize yourself and try to use Sets over Arrays whenever possible.