diff options
author | calvin-kargo <50098236+calvin-kargo@users.noreply.github.com> | 2022-01-04 03:26:53 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-03 21:26:53 +0100 |
commit | 4cb690440b4176bcfddd04323ac9118092fe3b31 (patch) | |
tree | 6274df0c9c74b32369fb972a3e7e3d965792df0d | |
parent | 40b512031f9ea68b4fbcf57d323cbedf4568cdfe (diff) | |
download | elixir-4cb690440b4176bcfddd04323ac9118092fe3b31.tar.gz |
Add assignment as generator documentation at for comprehension (#11534)
-rw-r--r-- | lib/elixir/lib/kernel/special_forms.ex | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/elixir/lib/kernel/special_forms.ex b/lib/elixir/lib/kernel/special_forms.ex index 0e7639cb0..6e0821bb5 100644 --- a/lib/elixir/lib/kernel/special_forms.ex +++ b/lib/elixir/lib/kernel/special_forms.ex @@ -1388,6 +1388,10 @@ defmodule Kernel.SpecialForms do iex> for n <- [1, 2, 3, 4, 5, 6], rem(n, 2) == 0, do: n [2, 4, 6] + Filters must evaluate to truthy values (everything but `nil` + and `false`). If a filter is falsy, then the current value is + discarded. + Generators can also be used to filter as it removes any value that doesn't match the pattern on the left side of `<-`: @@ -1408,6 +1412,35 @@ defmodule Kernel.SpecialForms do filters or inside the block, are not reflected outside of the comprehension. + Variable assignments inside filters must still return a truthy value, + otherwise values are discarded. Let's see an example. Imagine you have + a keyword list where the key is a programming language and the value + is its direct parent. Then let's try to compute the grandparent of each + language. You could try this: + + iex> languages = [elixir: :erlang, erlang: :prolog, prolog: nil] + iex> for {language, parent} <- languages, grandparent = languages[parent], do: {language, grandparent} + [elixir: :prolog] + + Given the grandparents of Erlang and Prolog were nil, those values were + filtered out. IF you don't want this behaviour, a simple option is to + move the filter inside the do-block: + + iex> languages = [elixir: :erlang, erlang: :prolog, prolog: nil] + iex> for {language, parent} <- languages do + ...> grandparent = languages[parent] + ...> {language, grandparent} + ...> end + [elixir: :prolog, erlang: nil, prolog: nil] + + However, such option is not always available, as you may have further + filters. An alternative is to convert the filter into a generator by + wrapping the right side of `=` in a list: + + iex> languages = [elixir: :erlang, erlang: :prolog, prolog: nil] + iex> for {language, parent} <- languages, grandparent <- [languages[parent]], do: {language, grandparent} + [elixir: :prolog, erlang: nil, prolog: nil] + ## The `:into` and `:uniq` options In the examples above, the result returned by the comprehension was |