How to Use The Ruby Select Method (With Examples)

You can use the select method in Ruby to filter an array of objects.

For example, you can find all the even numbers in a list.

Without select that looks like this:

even_numbers = []

[1,2,3,4,5,6].each do |n|
  if n.even?
    even_numbers << n
  end
end

even_numbers

That's quite a bit of code for something so simple!

Let's learn how to use select.

Select Method Example

Using select requires a block.

Inside the block, you have to return something that evaluates to true or false, and select will use that to filter your array.

You can learn about boolean values in Ruby by reading this article.

Here's an example:

[1,2,3,4,5,6].select { |n| n.even? }

This will do the same thing as the first example in the introduction, but with a lot less code.

In fact, we can reduce this even more.

Like this:

[1,2,3,4,5,6].select(&:even?)

This kind of shortcut only works when you have to call a method directly on every element of the array.

Btw, you can also use select with hashes.

Example:

stock = {
  apples: 10,
  oranges: 5,
  bananas: 1
}

stock.select { |k, v| v > 1 }

# {:apples=>10, :oranges=>5}

Where k represents the key & v represent the values.

I'm saying:

"Find me all the fruits with a stock greater than 1".

Combining Select With Other Methods

You can combine the select method with another Enumerable method.

Most notably with_index.

Example:

fruits = %w(apple orange banana)

fruits.select.with_index { |word, idx| idx.even? }

# ["apple", "banana"]

This allows you to filter using the index, instead of the object (in this case a string) itself.

In-Place Array Filtering

Using select on an array always creates a new array.

If instead you want to change the original array, you can use the select! method.

Here's how:

fruits = %w(apple orange banana)

fruits.select! { |fruit| fruit.start_with? "a" }

# ["apple"]

Methods that end with an exclamation mark (like select!) will change the object instead of returning a new one, but this rule is not enforced by the language itself.

It's just a convention between us.

Find vs Select

Select is great when you want to filter a list & get an array with the results.

But what if you want to find only one object?

You can use the find method.

Like this:

letters = %w(a aa aaa aaaa)

letters.find { |l| l.size == 3 }
# "aaa"

letters.find { |l| l.size == 10 }
# nil

Find gives you the first match, or nil if it can't be found.

Understanding The Find All Method

If you're wondering about the find_all method, and how it relates to find & select...

It's very simple!

  • The find_all method is an alias for select.
  • The find method helps you look for one specific object, instead of many objects.

Ruby 2.6 adds another alias for select:

filter

What's The Opposite Of Select?

You can remove elements that you don't want instead of selecting those that you do.

It's easy with select:

[1,2,3,4,5,6].select { |n| n != 4 }

But there is a method that makes things more clear.

That method is reject.

Example:

[1,2,3,4,5,6].reject { |n| n == 4 }

You don't get any technical advantage, in terms of performance or otherwise, but it will make your code better.

Rails Select Method

I don't want you to become confused when you work with Rails models & learn that you can also use select there.

You should know that...

This select method is different!

Example:

Fruit.select(:id, :name, :color)

When you use select with an ActiveRecord model you're asking for specific columns from the database.

As far as I understand this is mostly done for performance reasons.

One last note on this:

If you're working with a regular array inside a Rails app then you're using the select method we have been talking about during this whole article.

Summary

You have learned about select, one of Ruby's most helpful methods to work with collections of objects like arrays, ranges & hashes.

Ruby Select Mindmap

Now it's your turn to open your editor & use it.

Thanks for reading!

7 thoughts on “How to Use The Ruby Select Method (With Examples)”

Comments are closed.