Ruby find_all vs select, what’s the deal?
A month ago I knew absolutely nothing about the programming language Ruby. I had just interviewed using Javascript for Flatiron School where they teach both Javascript AND Ruby. Fast forward to now I can’t get enough of it!
Getting accepted to Flatiron School was just the beginning. One hundred hours of Ruby pre-work shortly followed where we learned tons of Ruby methods that we would need to build functional apps.
Of these methods in Ruby, find_all and select stood out to me because they seemed like they accomplished the same thing. Initial research led me to to find…
Wait, aren’t they identical!?
Well, sorta. A deeper dive into the Ruby docs led me to discover that there is a bit more under the hood.
An object is enumerable if it describes a set of items and a method to loop over each of them. In Ruby, Enumerable#find_all and Enumerable#select are the same code. Arrays in Ruby inherit from Enumerable, so running find_all or select on an Array in Ruby will yield the same result.
BUT it starts to get complicated when you are looping over a hash. A hash is a collection of key value pairs. If you’re more familiar with Javascript, a hash in Ruby is like an object in Javascript.
**On a hash, find_all returns an array**
hash = {a: 1, b: 2, c: 3, d: 4}hash.find_all do |key, value|
value.odd?
end#would return [[:a, 1], [:c, 3]] because the find_all method is #inherited from Enumerable
**On a hash, select returns a hash instead of an array**
hash = {a: 1, b: 2, c: 3, d: 4}hash.select do |key, value|
value.odd?
end#would return {a:1, c:3}
So why do find_all and select yield different results when running on a hash? With a Hash, find_all still inherits from Enumerable but select is redefined to return a Hash instead of an Array. Subtle but important difference!
Moral of the story, think about what you want to return when using select or find_all (and really any method in software engineering) before you use it!
Yay, we did it!
Sources: