Sets
In the past, JavaScript has always had very few built-in data structures. So basically, we only had objects and arrays. But in ES6, two more data structures were finally introduced: Sets and Maps. These are pretty common data structures that already exist in other programming languages, and now, they also exist in JavaScript. So in this lecture, let's learn all about sets.
A set is basically just a collection of unique values. i.e., a set can never have any duplicates, and that property makes them useful in certain situations. Let's start by creating a new set.
const ordersSet = new Set();
As written above, to create a new set, we use the new
keyword, and the argument we need to pass in to the set is an iterable. The most common iterable is an array.
const ordersSet = new Set([
'Pizza',
'Pasta',
'Risotto',
'Pasta',
'Risotto',
'Risotto',
'Pizza',
]);
In the above example, we added seven strings in our array, but of course, you can provide mixed data types, which will still be fine. We clearly see some duplicate strings in the array we provided to our set. So what do you think that this set will look like when we log it to the console?
console.log(ordersSet);
As you can see, we get a set! Our set has a size of three, and the only values in our set are: Pasta
, Pizza
and Risotto
. All the duplicates are gone, which confirms what we said earlier. We can also see that a set looks kind of similar to an array. There are no key-value pairs. It's just a bunch of values grouped, in this case, into a set. And just like arrays, sets are also iterables.
Sets are still very different from arrays for two main reasons: first, elements in a set are unique, and second, the order of elements is irrelevant. We will see why in a second. But anyway, keep in mind that strings are also iterables.
console.log(new Set('Ulrich'));
You can also decide to create an empty set which is totally fine.
console.log(new Set());
Let's now learn how to work with sets. First off, we can get the size of a set.
/**
* size for Sets
* length for Arrays
*/
console.log(ordersSet.size); // Result ==> 3
In this particular example, this might be useful for the restaurant chef 🧑🍳 to know how many different meals will be cooked. In other words, if the array that we passed to our set (['Pizza', 'Pasta', ...]
) is an array of all the orders, then the set of these orders are simply the different unique meals that will be cooked. And then the size is how many different meals will be cooked.
Next, we can check if a specific element is in a set.
console.log(ordersSet.has('Pizza')); // Result ==> true
console.log(ordersSet.has('Focaccia')); // Result ==> false
Comparing it to arrays, the has
method is similar to the includes
method in arrays.
Next step, we can also add new elements to a set. Let's say that now someone ordered 'Garlic Bread'
. And let's say that it happened twice. So, we will end up with something like this:
ordersSet.add('Garlic Bread');
ordersSet.add('Garlic Bread');
What do you think the set will look like when we log it? 😏
console.log(ordersSet);
'Garlic bread'
got added but only once because the set has to be unique.
Finally we can also delete elements in a set.
console.log('BEFORE DELETE');
console.log(ordersSet);
console.log('DELETING...');
/**
* delete returns a boolean
*
* true ==> If the element was found and deleted
* false ==> If the element was not foud and was not deleted
*/
console.log(ordersSet.delete('Pasta'));
console.log('AFTER DELETE');
console.log(ordersSet);
You might now ask yourself: how do we retrieve values from a set? Can we use an index, like in arrays? The answer is no! Because, doing something like ordersSet[0]
we give us undefined
console.log(ordersSet[0]); // Result ==> undefined
The reason is that, in sets, there are actually no indexes. And in fact, there is no way of getting values out of a set. If we think about this, then it makes sense. There's no need to get data out of a set. If all values are unique and their order does not matter, then there is no point in retrieving values out of a set.
All we really need to know is whether a certain value is in the set or not. That's why we have the has
method. If your goal is to store values in order and retrieve them, the best use case is to use an array. You wouldn't use a set for that.
Finally, there is one more method we can use to delete all of the set elements.
console.log('BEFORE DELETE');
console.log(ordersSet);
console.log('DELETING ALL ELEMENTS...');
ordersSet.clear();
console.log('AFTER DELETE');
console.log(ordersSet);
As I said earlier, sets are also iterables. Hence, we can loop over them.
for (const order of ordersSet) {
console.log(order);
}
Now that we know how to work with sets, let's see an actual use case. In a normal code base, the main use case of sets is to remove duplicate values in arrays. Let's consider an array that contains our restaurant's staff.
const staff = [
'Waiter',
'Chef',
'Cashier',
'Manager',
'Cashier',
'Waiter',
'Chef',
];
Next, for some reason, we are now interested in knowing only which different positions there are in our restaurant. Or, in other words, we would like to have our staff
array without all the duplicates. So let's create a set for that.
const staffSet = new Set(staff);
console.log(staffSet);
We now want our staffSet
to be an array. But the conversion from a set to an array is pretty easy because they are both iterables. Remember from earlier that the spread operator works on all iterables including sets. So, to convert our set to an array, we can do this:
const staffSet = new Set(staff);
const staffArray = [...new Set(staff)];
/**
* OR
*
* const staffArray = [...staffSet]
*/
If we only wanted to know how many different positions there are, then the size
property is very useful.
console.log(new Set(staff).size);
Same for counting how many different letters there are in a string. This can be done because remember a string is also an iterable.
console.log(new Set('components').size); // Result ==> 8
To conclude this lecture, sets do not intend to replace arrays at all. Always use arrays whenever you need to store values in order, which might contain duplicates. That's also true when you need to manipulate data because arrays have access to many great array methods that we're going to study a little bit later.
Now sets have this very useful property of being unique. And it's also very easy to interact with sets by using all of their straightforward methods. However, they are not nearly as important as arrays. So keep sets in mind when you need to work with unique values. But besides that, you can continue using arrays.