如何将键值对放入具有变量键名称的映射中

Dan*_*_es 6 elixir

我试图最终得到一个包含许多不同首选项的地图,它应该如下所示:

%{some_preference_name:%{foo:"bar"},another_preference_name:%{foo:"bar"}}
Run Code Online (Sandbox Code Playgroud)

我有一个数据库中的首选项映射列表,我需要通过它们并将"首选项"字段设置为键,其中各种值作为值映射.

我尝试用Enum.reduce和Enum做地图,但我无法将列表正确.

Enum.map(preferences, fn(data)->
  Map.put(%{}, data.preference,
   %{
     foo: data.foo
    }
  )
end)
Run Code Online (Sandbox Code Playgroud)

收益:

[{some_preference_name:%{foo:"bar"}},{another_preference_name:%{foo:"bar"}}]
Run Code Online (Sandbox Code Playgroud)

然后:

Enum.reduce(preferences, fn(acc, data)->
  Map.put(acc, data.preference,
   %{
     foo: data.foo
    }
  )
end)
Run Code Online (Sandbox Code Playgroud)

收益:

%{some_preference_name:%{foo:"bar"},preference: "another_preference_name",foo:"bar"}
Run Code Online (Sandbox Code Playgroud)

它得到第一个正确,但不是其余的.据我所知,从Erlang R17开始,我能够添加变量键名的唯一方法是使用Map.put/3.

Jos*_*lim 12

你的代码几乎是正确的,你刚刚在reduce函数中交换了参数顺序:

Enum.reduce(preferences, fn(data, acc)->
  Map.put(acc, data.preference, %{foo: data.foo})
end)
Run Code Online (Sandbox Code Playgroud)


sob*_*evn 9

你现在可以(因为Elixir 1.2.0)没有任何黑客攻击.这在更改概述的语言改进部分中列出.

那是怎么做的:

iex> key = :hello
iex> value = "world"
iex> %{key => value}
%{:hello => "world"}
Run Code Online (Sandbox Code Playgroud)

如果你想模式匹配一​​个现有的变量 - 使用^运算符:

iex> key = :hello
iex> %{^key => value} = %{:hello => "another world"}
iex> value
"another world"
Run Code Online (Sandbox Code Playgroud)