Thank you for joining me as I share my favorite functions and patterns in functional programming. Today’s focus is on the function group_by
. Previously, I published Function: with
Statement and Function: Curry. This is the third installation in the series. For all of this week’s functions and patterns, visit the Index.
I encountered this little gem while pair-programming with a colleague. It affords much potential in the domain of complex sorting operations.
Say we’ve a large list of unsorted, unordered exam results:
def list_exam_results do
[
%{name: "Zelda", score: 56},
%{name: "Eddy", score: 58},
%{name: "Jack", score: 69},
%{name: "Abby", score: 84},
%{name: "Lily", score: 96}
]
end
First, we want to segregate records by letter grade (e.g., A, B, C, D, F), and then, for each group, we want to order results by student name
. Elixir’s Enum.group_by
is perfect.
Implementations of group_by
generally take a list of items and then a predicate. Our predicate might look something like:
def by_grade(%{score: score}) do
cond do
score < 65 -> "F"
score < 70 -> "D"
score < 80 -> "C"
score < 90 -> "B"
true -> "A"
end
end
Which will take any of our records from list_exam_results
and return a letter grade. On its own:
Enum.group_by(list_exam_results(), &by_grade(&1))
Will return:
%{
"A" => [%{name: "Lily", score: 96}],
"B" => [%{name: "Abby", score: 84}],
"D" => [%{name: "Jack", score: 69}],
"F" => [%{name: "Zelda", score: 56}, %{name: "Eddy", score: 58}]
}
We’ve now positioned our data so that its subsets can be sorted by letter grade. Our final group_by
implementation might resemble:
def prepare_records(coll \\ list_exam_results()) do
coll
|> Enum.group_by(&by_grade(&1))
|> Enum.map(fn {_letter_grade, subset} -> Enum.sort(subset) end)
end
Which will give us:
[
[%{name: "Lily", score: 96}],
[%{name: "Abby", score: 84}],
[%{name: "Jack", score: 69}],
[%{name: "Eddy", score: 58}, %{name: "Zelda", score: 56}]
]
With Zelda
‘s record appearing after Eddy
.
Resources
We're building an AI-powered Product Operations Cloud, leveraging AI in almost every aspect of the software delivery lifecycle. Want to test drive it with us? Join the ProdOps party at ProdOps.ai.