F3.04 · part 2 of 3
Comprehensions
A comprehension — for — is a compact way to walk one or more
enumerables and build a collection. A generator draws elements, a filter
drops the ones you do not want, and :into chooses what the result is collected into.
It is set-builder notation, written as code.
The portal uses comprehensions to turn progress records into reports — a list of ids, a map keyed by course, or every valid pairing of course and lesson.
Build a comprehension
Over the same five progress records, each form below adds one capability. Select one to see the
for expression and the shape of what it returns.
Comprehension form · select one
Read it left to right: draw from a generator, keep what passes the filters, collect into the
target. For a single map-or-filter, Enum is often clearer; comprehensions earn their
keep with multiple generators and :into.
Generators, filters, into
Every part is optional except one generator. Generators can pattern-match, and a non-matching element is skipped silently — a tidy way to filter by shape.
# generator, filter, mapping body for r <- progress, r.completed, do: r.lesson_id # :into collects into something other than a list for r <- progress, into: %{}, do: {r.course, r.lesson_id} # a matching generator skips records that do not match for %{completed: true, lesson_id: id} <- progress, do: id
F1 · set-builder notation
{ id(r) | r ∈ progress, completed(r) }
F3 · the comprehension
for r <- progress, r.completed, do: id(r)
Next: lazy streams — the same traversals, deferred until a result is pulled.
References
Primary sources for this lesson, and where it connects in the course.