How to Use The Ruby Set Class

What is a Ruby set?

A set is a class that stores items like an array…

But with some special attributes that make it 10x faster in specific situations!

On top of that:

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 your maximum benefit
  • The difference between sets & arrays!
  • A list of useful set methods

Let’s get started!

Ruby Set Examples

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:

  1. require ‘set’
  2. products = Set.new
  3. products << 1
  4. products << 1
  5. products << 2
  6. products
  7. Set: {1, 2}

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

  1. products.include?(1)
  2. true

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

Set vs Array - Understanding The Difference

Now you may be wondering…

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

A set has no direct access to elements:

  1. products[0]
  2. undefined method `[]’

That’s the main difference.

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

  1. products.to_a
  2. [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.

Set vs Array Benchmark

Here’s a benchmark to show you the performance difference between array & set include? methods.

  1. Ruby 2.5.0

  2. set include: 8381985.2 i/s
  3. 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.

Ruby Set Methods

One of the useful set methods is the union operator :

  1. products | (1…10)
  2. 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 :

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

And here’s the set intersection operator:

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

This gives you the elements common in both sets.

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

Superset & Subset

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 :

  1. 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:

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

How to Use Sorted Sets

If you want a set that always stays sorted you can use the SortedSet class.

There are some requirements to using this class:

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

Here’s an example:

  1. sorted_numbers = SortedSet.new
  2. sorted_numbers << 5
  3. sorted_numbers << 2
  4. sorted_numbers << 1
  5. sorted_numbers
  6. SortedSet: {1, 2, 5}

Refer: https://www.rubyguides.com/2018/08/ruby-set-class/