如何将键值对放入具有可变键名的映射中
How to put key value pair into map with variable key name
我想最终得到一张包含许多不同偏好的地图,它应该如下所示:
%{some_preference_name:%{foo:"bar"},another_preference_name:%{foo:"bar"}}
我有一个来自数据库的偏好映射列表,我需要通过它们并将 "preference" 字段设置为键,将各种值作为值映射。
我尝试用 Enum.reduce 和 Enum,map 来做到这一点,但我无法获得正确的列表。
Enum.map(preferences, fn(data)->
Map.put(%{}, data.preference,
%{
foo: data.foo
}
)
end)
returns:
[{some_preference_name:%{foo:"bar"}},{another_preference_name:%{foo:"bar"}}]
然后:
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"}
第一个正确,但其余的不正确。我知道从 Erlang R17 开始,我能够添加变量键名的唯一方法是使用 Map.put/3.
尝试使用 hd()
和 tl()
递归来获取列表项,而不是 Enum.map
和 Enum.reduce
。
def get_preference() do
preferences = [%{:preference => "some_preference_name", :foo => "bar"}, %{:preference => "another_preference_name", :foo => "rab"}]
convert(preferences, %{})
end
def convert([], map) do
map
end
def convert([head|tail], map) do
map = Map.put(map, head.preference, %{foo: head.foo})
convert(tail, map)
end
希望对你有用。
您的代码几乎是正确的,您刚刚交换了 reduce 函数中的参数顺序:
Enum.reduce(preferences, fn(data, acc)->
Map.put(acc, data.preference, %{foo: data.foo})
end)
您现在(自 Elixir 1.2.0
起)无需任何技巧即可完成。
这在 the changes overview.
的语言改进部分中列出
这是怎么做的:
iex> key = :hello
iex> value = "world"
iex> %{key => value}
%{:hello => "world"}
如果您想模式匹配现有变量 - 使用 ^
运算符:
iex> key = :hello
iex> %{^key => value} = %{:hello => "another world"}
iex> value
"another world"
我想最终得到一张包含许多不同偏好的地图,它应该如下所示:
%{some_preference_name:%{foo:"bar"},another_preference_name:%{foo:"bar"}}
我有一个来自数据库的偏好映射列表,我需要通过它们并将 "preference" 字段设置为键,将各种值作为值映射。
我尝试用 Enum.reduce 和 Enum,map 来做到这一点,但我无法获得正确的列表。
Enum.map(preferences, fn(data)->
Map.put(%{}, data.preference,
%{
foo: data.foo
}
)
end)
returns:
[{some_preference_name:%{foo:"bar"}},{another_preference_name:%{foo:"bar"}}]
然后:
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"}
第一个正确,但其余的不正确。我知道从 Erlang R17 开始,我能够添加变量键名的唯一方法是使用 Map.put/3.
尝试使用 hd()
和 tl()
递归来获取列表项,而不是 Enum.map
和 Enum.reduce
。
def get_preference() do
preferences = [%{:preference => "some_preference_name", :foo => "bar"}, %{:preference => "another_preference_name", :foo => "rab"}]
convert(preferences, %{})
end
def convert([], map) do
map
end
def convert([head|tail], map) do
map = Map.put(map, head.preference, %{foo: head.foo})
convert(tail, map)
end
希望对你有用。
您的代码几乎是正确的,您刚刚交换了 reduce 函数中的参数顺序:
Enum.reduce(preferences, fn(data, acc)->
Map.put(acc, data.preference, %{foo: data.foo})
end)
您现在(自 Elixir 1.2.0
起)无需任何技巧即可完成。
这在 the changes overview.
这是怎么做的:
iex> key = :hello
iex> value = "world"
iex> %{key => value}
%{:hello => "world"}
如果您想模式匹配现有变量 - 使用 ^
运算符:
iex> key = :hello
iex> %{^key => value} = %{:hello => "another world"}
iex> value
"another world"