July 09, 2015
Ruby’s #group_by method provides a way to (wait for it) group things by some arbitrary property. It’s part of the Enumerable module, so you can generally use it anywhere you’d be using #each
or some iteration. To use #group_by
, you first need to know two things:
#group_by
returns a hash where the keys are defined by our grouping rule, and the values are the corresponding objects from our original collection.
Now let’s look at three examples of #group_by
in action!
# Create a list of names
names = ["Ripley", "McClane", "Ryerson", "Murphy"]
# group by first letter
names_by_letter = names.group_by { |name| name[0] }
#{
# "R" => [
# [0] "Ripley",
# [1] "Ryerson"
# ],
# "M" => [
# [0] "McClane",
# [1] "Murphy"
# ]
#}
# generate random numbers
numbers = (1..99).to_a.sample 50
# group by quotient (number divided by 20)
data.group_by { |number| number / 20 }
#{
# 3 => [
# [0] 78,
# [1] 61,
# [2] 67,
# [3] 65,
# [4] 68,
# [5] 71,
# [6] 76,
# [7] 70,
# [8] 64,
# [9] 60
# ],
# 1 => [
# [ 0] 24,
# [ 1] 39,
# [ 2] 28,
# [ 3] 20,
# [ 4] 26,
# [ 5] 31,
# [ 6] 29,
# [ 7] 35,
# [ 8] 32,
# [ 9] 33,
# [10] 30
# ],
# 2 => [
# [0] 49,
# [1] 57,
# [2] 46,
# [3] 51,
# [4] 52,
# [5] 42,
# [6] 55,
# [7] 58
# ],
# 4 => [
# [0] 84,
# [1] 80,
# [2] 93,
# [3] 91,
# [4] 92,
# [5] 86
# ],
# 0 => [
# [ 0] 10,
# [ 1] 9,
# [ 2] 13,
# [ 3] 14,
# [ 4] 8,
# [ 5] 17,
# [ 6] 18,
# [ 7] 11,
# [ 8] 2,
# [ 9] 7,
# [10] 4,
# [11] 3,
# [12] 19,
# [13] 15,
# [14] 5
# ]
#}
# Create a list of objects
array_of_fun = ["Bob", 89, [1, 2, 3], Hash.new, (0..10).to_a, "Gene", 5]
# group objects by class
array of fun.group_by { |thing| thing.class }
#{
# String < Object => [
# [0] "Bob",
# [1] "Gene"
# ],
# Fixnum < Integer => [
# [0] 89,
# [1] 5
# ],
# Array < Object => [
# [0] [
# [0] 1,
# [1] 2,
# [2] 3
# ],
# [1] [
# [ 0] 0,
# [ 1] 1,
# [ 2] 2,
# [ 3] 3,
# [ 4] 4,
# [ 5] 5,
# [ 6] 6,
# [ 7] 7,
# [ 8] 8,
# [ 9] 9,
# [10] 10
# ]
# ],
# Hash < Object => [
# [0] {}
# ]
#}
These are pretty contrived examples, but when combined with other methods, #group_by can be a handy way to get your objects in order. Now go get grouping!