fun with group_by
Using Ruby's #group_by Method
Friday, April 10th, 2015
back to blog index
I really don't mind reading the Ruby documentation. Actually, I secretly kind of like it. Living in Oakland, I spend a decent amount of time on the train, and I sometimes browse through the method pages. But of course, there's many, many methods I don't know about.
One method was from the Enumerable class, #group_by. The name sort of suggests what it does, and the documentation is pretty straight-forward: "Groups the collection by the result of the block." Ok, great! How can it be used? "Returns a hash where the keys are the evaluated result from the block and the values are arrays of elements in the collection that correspond to the key." Ok!... and, that's why there's examples. Here's the one from the ruby-doc.org page:
(1..6).group_by { |i| i % 3 }
#=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
Let’s say I have a list of friends in an array (oh, I explored those last week!):
friends = ["Sam", "Kevin", "Brian", "Steve",
"Pete", "Todd", "Frank", "Elliot", "George"]
I could look at them and think, “Wow, pretty generic-looking names. And whoa, lots are five letters long." How many? I could use the #group_by method like so, and it would return:
friends.group_by { |friend| friend.length }
{3=>["Sam"], 5=>["Kevin", "Brian", "Steve", "Frank"],
4=>["Pete", "Todd"], 6=>["Elliot", "George"]}
Not bad! We could also do this with hashes! Now let’s assume my nine friends make up a baseball team, and I have a hash with their names and their batting averages. (If you aren’t a baseball fan, I’m sorry. Just think of the numbers like percentages, and the higher, the better.)
players = {
"Pete" => 0.320,
"Kevin" => 0.221,
"Brian" => 0.212,
"Steve" => 0.302,
"Dylan" => 0.198,
"Todd" => 0.244,
"Frank" => 0.311,
"Elliot" => 0.141,
"George" => 0.267
}
If I want to find which ones are batting over “.250” (baseball people leave off that zero…) I could use #group_by again, and get them sorted!
players.group_by { |name, avg| avg > 0.25 }
{true=>[["Pete", 0.32], ["Steve", 0.302], ["Frank", 0.311], ["George", 0.267]], false=>[["Kevin", 0.221], ["Brian", 0.212], ["Dylan", 0.198], ["Todd", 0.244], ["Elliot", 0.141]]}
Awesome! (Well, the method is. The baseball team could use a few new players). Like with most things in object-oriented programming, the true challenge is just thinking how to translate a real-world idea into code. The language structure allows us to interact with countless representations of objects. We could alphebetize, group by color, or sort by birthday. Whatever the goal, if we can figure out a block of code to make it happen, we’re in business. Play around a bit and see if you can think of some good ones, and let me know. Happy grouping!
back to blog index