Comprehension provide a facility for transforming Enumerables easily and declaratively. They are syntactic sugar for iterating through enumerables in Elixir.
for s <- ["a", "b", "hello", "c"], # 1. generator
String.length(s) == 1, # 2. filter
into: "", # 3. collectable
do: String.upcase(s)
# => "ABC"
There are three parts to a comprehension:
There are single- and multi-line comprehensions. When more than one generator is used, a cartesian product of the values generated is enumerated. That means that each value generated by the first generator will be paired once with each value generated by the second generator.
for n <- [0, 1, 2, 3], do: n + 1
# => [1, 2, 3, 4]
for x <- [0, 1],
y <- [0, 1] do
{x, y}
end
# => [{0, 0}, {0, 1}, {1, 0}, {1, 1}]
The value in the do-block is inserted into the collectable for each value generated from the enumerable.
for _ <- [1, 2, 3], do: :a
# => [:a, :a, :a]
Pattern matching can occur in the comprehension, either on the left side of the <-
or on their own line.
for {atom, str} <- [a: "string"], do: str
# => ["string"]
for pair <- [a: "string"],
{atom, str} = pair do
str
end
# => ["string"]