for iterates over a list of elements, which a plain pattern match does not do.
for a when is_atom(a) <- [:a, :b, :c], do: a
# [:a, :b, :c]
vs.
[:a | _] = [:a, :b, :c]
If you iterate over a map (similar to iterating over a keyword list) each individual element is a tuple of {key, value}, which is what you’re matching on in your for example.
there is no pattern matching taking place. The match operator is =, and that line has no = sign in it.
In this line:
{_key, [value]} = convert_errors
there is a match operator, but the thing on the left is a tuple and the thing on the right is a map, and a tuple can never match a map. Similarly, the list [1,2,3] can never match the tuple {1, 2, 3}.
To extract values from a map with pattern matching, you need to write:
@NobbZ, thank you , I don’t know how it works, for the sake of this I’m just asking.
I have edited my code like this:
%{_ => value} = %{"mobile" => ["mobile number"] }
but I have this error:
** (CompileError) iex:2: cannot use variable _ as map key inside a pattern. Map keys in patterns can only be literals (such as atoms, strings, tuples, etc) or an existing variable matched with the pin operator (such as ^some_var)
(stdlib) lists.erl:1263: :lists.foldl/3
I’m feeling I have no control on my code, I need to have key and value in pattern just for learning.
Because its not a valid pattern, I used a conjunctive form. A short sentence that should make you clear, that if and only if %{_ => value} were (but it actually is not) valid, then you had a problem with values like %{foo: [:bar], baz: [:quux]}.
Thank you, I understood what you was saying, then at last what is your suggestion to handle these maps? using elixir module or for loop to get one map not maps !!?
I’m a bit confused here. You say you want to improve your pattern matching skills, but you also seem to have a very specific set of constraints (has to be a for comprehension and the map values have to be a List, (and you don’t want to use any module – which I understand even less)) and a very specific data structure as if you were working on a real problem.
If I’m guessing right, this might be helpful to you
for {_key, values} <- convert_errors, is_list(values), value <- values do
IO.inspect(value)
end
This takes advantage of a lesser known part of for comprehensions called filters. The is_list(values) is the filter that only considers lists. Then after that, we further look at each element of the list.
Thank you for your commenting, Actually I’m trying to improve myself and translate some elixir documents to Persian, For this purpose I saw this problem in my work.
thank you all I will use all of your hints.
for {_key, value} <- convert_errors do
IO.inspect value
end
For each tuple {_key, value} which is an element of the collection/enumeration named convert_errors …
{_key, [value]} = convert_errors
Match the (single) value named convert_errors with the tuple pattern {_key,[value]} pattern, whereupon a successful match the value is destructured according to the pattern and the subvalues are bound to the names _key and value (the leading underscore in _key indicating that the contents bound to the name _key will not be used any further).