How to put key value pair into map with variable key name

12,254

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"
Share:
12,254
Dania_es
Author by

Dania_es

Updated on July 23, 2022

Comments

  • Dania_es
    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.