The :into
option
In the examples above, all the comprehensions returned lists as their result. However, the result of a comprehension can be inserted into different data structures by passing the :into
option to the comprehension.
For example, a bitstring generator can be used with the :into
option in order to easily remove all spaces in a string:
iex> for <<c <- " hello world ">>, c != ?\s, into: "", do: <<c>>
"helloworld"
Sets, maps and other dictionaries can also be given to the :into
option. In general, :into
accepts any structure that implements the Collectable
protocol.
A common use case of :into
can be transforming values in a map, without touching the keys:
iex> for {key, val} <- %{"a" => 1, "b" => 2}, into: %{}, do: {key, val * val}
%{"a" => 1, "b" => 4}
Let’s make another example using streams. Since the IO
module provides streams (that are both Enumerable
s and Collectable
s), an echo terminal that echoes back the upcased version of whatever is typed can be implemented using comprehensions:
iex> stream = IO.stream(:stdio, :line)
iex> for line <- stream, into: stream do
...> String.upcase(line) <> "\n"
...> end
Now type any string into the terminal and you will see that the same value will be printed in upper-case. Unfortunately, this example also got your IEx shell stuck in the comprehension, so you will need to hit Ctrl+C
twice to get out of it. :)