'How do I write the function to pass to Enum.map when enumerating a map?
iex(121)> val_map = %{"pri" => %{"tit" => "name1"}}
iex(122)> fp = fn (new_map) -> Map.get(new_map, "pri") end
following raises error
iex(123)> Enum.each(val_map, fp)
** (BadMapError) expected a map, got: {"pri", %{"tit" => "name1"}}
(elixir) lib/map.ex:437: Map.get({"pri", %{"tit" => "name1"}}, "pri", nil)
(elixir) lib/enum.ex:771: anonymous fn/3 in Enum.each/2
(stdlib) maps.erl:257: :maps.fold_1/3
(elixir) lib/enum.ex:1941: Enum.each/2
Solution 1:[1]
It's hard to tell from your code what your objective is, maybe you are just experimenting with Enum, but maybe Map.values/1 is a better choice here?
iex(1)> val_map = %{"pri" => %{"tit" => "name1"}, "sec" => %{"tat" => "name2"}}
%{"pri" => %{"tit" => "name1"}, "sec" => %{"tat" => "name2"}}
iex(2)> Map.values(val_map)
[%{"tit" => "name1"}, %{"tat" => "name2"}]
Responding to the clarification in the comments, you can do it like this:
iex(1)> val_map = %{"pri" => %{"tit" => "name1"}, "sec" => %{"tit" => "name2"}}
%{"pri" => %{"tit" => "name1"}, "sec" => %{"tit" => "name2"}}
iex(2)> Enum.map(val_map, fn {k, %{"tit" => v}} -> %{k => v} end)
[%{"pri" => "name1"}, %{"sec" => "name2"}]
Solution 2:[2]
When you iterate over a Map, it will turn it into a Keyword List (i.e. you use a tuple):
Enum.each %{a: 1, b: 2, c: 3}, fn {key, value} ->
IO.puts "#{key} : #{value}"
end
In your case, you need to match on the key part of you tuple:
val_map = %{"pri" => %{"tit" => "name1"}}
fp = fn ({"pri", value}) -> value; {other_key, value} -> value end
Where in the second part you can do something else with the value: transform, don't return it, etc.
In this case it will return an array of Maps (values) from your initial map:
Enum.each(val_map, fp)
# [%{"tit" => "name1"}]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Máté |
