How to put key value pair into map with variable key name
Solution 1
Your code is almost correct, you have just swapped the arguments order in the reduce function:
Enum.reduce(preferences, fn(data, acc)->
Map.put(acc, data.preference, %{foo: data.foo})
end)
Solution 2
You can now (since Elixir 1.2.0
) do it without any hacks.
This is listed in the language improvements section in the changes overview.
That is how to do it:
iex> key = :hello
iex> value = "world"
iex> %{key => value}
%{:hello => "world"}
And if you want to pattern match an existing variable - use ^
operator:
iex> key = :hello
iex> %{^key => value} = %{:hello => "another world"}
iex> value
"another world"
Dania_es
Updated on July 23, 2022Comments
-
Dania_es almost 2 years
I'm trying to end up with a single map containing many different preferences, it should look like this:
%{some_preference_name:%{foo:"bar"},another_preference_name:%{foo:"bar"}}
I have a list of preference maps from the database, and I need to get through them and set the "preference" field as the key with the various values as the values map.
I tried to do this with Enum.reduce and Enum,map, but I can't get the list right.
Enum.map(preferences, fn(data)-> Map.put(%{}, data.preference, %{ foo: data.foo } ) end)
returns:
[{some_preference_name:%{foo:"bar"}},{another_preference_name:%{foo:"bar"}}]
then:
Enum.reduce(preferences, fn(acc, data)-> Map.put(acc, data.preference, %{ foo: data.foo } ) end)
returns:
%{some_preference_name:%{foo:"bar"},preference: "another_preference_name",foo:"bar"}
It gets the first one right, but not the rest. I understand that as of Erlang R17, the only way I will be able to add a variable key name is with Map.put/3.