Revelry

AI-Driven Custom Software Development

# My Favorite Functions and Patterns: group_by

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.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.