Searching through nested data structures can be downright messy. Even saying “nested data structures” sounds complicated. Luckily, Ruby has some powerful Enumerable methods that can simplify our lives (or at least our code).
Let’s say you’ve been programming for hours and suddenly realize your stomach is growling at you (why does this happen so often?). Here is how you might search for some delicious food, if you happened to be searching inside an array filled with hashes. Just humor me for the sake of example.
Here is our restaurants
array:
1 2 3 4 5 6 |
|
So, we want to get the name of a restaurant whose :rating
is "delicious"
. We could do something like this:
1 2 3 4 5 6 7 8 9 |
|
If we call this method on our restaurants
hash, it will return the value “The GoGo Grill”. Sounds good to me. But in order to get there we needed a return
inside an if
statement inside an each
loop inside another each
loop. Not pretty.
There is a better way. The find
method! Behold:
1 2 3 |
|
Just one line of code seems to do the same thing as its ugly predecessor. Let’s look at it more closely. Here is what find
does:
- It passes each element of the object on which it was called to a block.
- It returns the first element for which the block evaluates to
true
. - If none of the elements return true for the given block, it returns
nil
.
As it turns out, this nil
value could cause some problems for our find_delicious_food
method. If there are no restaurants in the hash with a :rating
of "delicious"
, our code breaks. We would get an error, because Ruby cannot make any sense out of nil[:name]
.
Here is the method refactored to avoid that error:
1 2 3 4 5 6 |
|
Sure, it may not be as cute and little as our one-line method, but it will never break and it’s still a lot prettier than loops inside loops.
So when you are searching for that one thing you need inside of some nasty nesting, just find
it!