A set is a class that can hold items in a similar way that an array does…

…but with some special attributes.

With the main benefit being this:

All the items in a set are **guaranteed to be unique**.

In this Ruby tutorial you’ll learn:

- How & when to use a set for maximum benefit
- The difference between sets & arrays
- A list of useful set methods

Let’s get started!

A set is a Ruby class that helps you **create a list of unique items**.

Here’s an example of how this is useful:

Let’s say you are going over a big list of products.

But **there are duplicated entries** in this list & you only want unique products.

You could put them in a set, and the set will make sure your product list is always unique **without any extra work**.

Here’s how to do that:

require 'set' products = Set.new products << 1 products << 1 products << 2 products # Set: {1, 2}

Another benefit is that **searching this list is going to be very fast**:

products.include?(1) # true

This is so fast because the search is made in constant time.

Now you may be wondering...

What's the difference between a set & an array?

A set has no direct access to elements:

products[0] # undefined method `[]'

That's the main difference.

But **a set can be converted into an array** any time you need:

products.to_a # [1, 2]

The whole point of using a set is to use its two special attributes:

- Fast lookup times (with
`include?`

) - Unique values

If you need these then **a set will give you a good performance boost**, and you won't have to be calling `uniq`

on your array every time you want unique elements.

Here's a benchmark to show you the performance difference between array & set `include?`

methods.

# Ruby 2.5.0 set include: 8381985.2 i/s array include: 703305.5 i/s - 11.92x slower

The reason for this difference is that **an array has to check every single element**...

...if you have a 1 million element array it's going to be checking 1 million elements every time you call `include?`

.

A set doesn't have to do that.

One of the useful set methods is **the union operator**:

products | (1..10) # Set: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

This works with any Enumerable object, like arrays, ranges & hashes.

Here's the **difference operator**:

products - (3..4) # Set: {1, 2, 5, 6, 7, 8, 9, 10}

And here's the **set intersection** operator:

Set.new(1..3) & Set.new(2..5) # Set: {2, 3}

This gives you the elements common in both sets.

These 3 operators (union, difference & intersection) can also be used with arrays.

A superset is **a set that contains all the elements of another set**.

You can check if one set is a superset of another.

**Like this**:

Set.new(10..40) >= Set.new(20..30)

The range `10..40`

contains `20..30`

within it.

A **subset** is a set that is made from parts of another set:

Set.new(25..27) <= Set.new(20..30)

If you want a set that **always stays sorted** you can use the `SortedSet`

class.

There are some requirements to using this class:

- The objects you are adding to the set
**must implement**the <=> method. - The objects
**must be comparable to each other**(comparing integer to integer, or string to string)

Here's an example:

sorted_numbers = SortedSet.new sorted_numbers << 5 sorted_numbers << 2 sorted_numbers << 1 sorted_numbers # SortedSet: {1, 2, 5}

You learned how to use sets in Ruby for better performance & easier coding. You also learned about the differences between arrays & sets.

Please share this article if you found it useful so more people can find it ðŸ™‚

Thanks for reading!