Playing with Ruby Sets.
The Set class in Ruby offers to us, well, basically sets and the ability to do operations on it. Like the sets from mathematics.
In some cases, we need to have a set of values without duplications, in this cases know a little bit about how to use Sets will make our code to shine and help a lot to boost our performance.
We will start to understand better how Sets works playing around some examples:
Let’s imagine some case where we need to play with a large in-memory set of components, and we need to end having unique values inside there. Instead of starting doing verifications and checking each one of our elements, where the processing time will increase together with the size of our set, we can use the set library to do the job for us.
Looking to the final set of names you can see that the values
John Locke wasn’t added twice and we don’t need to add any extra verification to skip it before that add method.
(Don’t forget to use that
require "set" when you’re planning to use the set feature on your code.)
Now, let’s take two ranges of values as an example, where the intersection between they have some duplicated values.
If we simply take these both and sum the elements size, we will get 90 as you can see:
So, to start using the powers of sets in these two ranges, we have two basic options to make it happens. We can just use the method
to_set to convert the object from a type of Range to a type of Set, or we can also instantiate a
new Set object passing our range as the argument. Let’s see both in practice:
1) Using the method
If we forgot to required the ruby set implementation using
require 'set' then we will get back an error like:
Otherwise, we will able to see our new
2) Instantiating a new Set object
As we mentioned before, we can instantiate a new Set object passing our range as the argument:
Finally, with our ranges converted to the Set class, we can start to make playing with some set operations, like for example the union of both sets:
Did you remember how many elements we got before when we summed the size of the two sets using the class Range? Exactly, 90 elements. Right now we’re getting 70 and successfully skipping the duplicated interval from 20 to 40.
A good observation to make at this point is if we tried to sum that two ranges we will get back an epic failure as we can see above:
That’s why we used the
size method before to know how many elements we have in both ranges instead of just try to sum both directly using the
+ operator (method) as we’re doing with sets now.
Some others syntax sugar available to the
+ operator is the
| and also the
union as we can observe above:
Anyway, if we are looking for the difference between one set and the other, we can use the
we can get the full difference of both sets doing:
or we can simply use the
^ method to get the same:
To get the intersection between our sets we can use the
So, if you need not have duplicate values in some set of elements doing fast lookups, then you should consider using the Ruby Set class.
There’s also other operations available to improve our job using sets in ruby, but for now, I believe it’s enough to remember how it works and maybe start using it in the future.