像这样的地图列表如何将some_maps = [%{"test" => [1]}, %{"test2" => [2]}, %{"test" => [3]}]其值合并为一张巨大的单一地图?
single_map = %{"test" => [1, 3], "test2" => [2]}
Run Code Online (Sandbox Code Playgroud)
由于我无法在迭代中修改地图,就像for我不知道如何构建该地图
用其他语言,我将定义一个空的地图并遍历列表并填充该地图,但从功能上来说,我认为我看不到该怎么做。
这是一种实现方法:
Enum.reduce(some_maps, fn x, y ->
Map.merge(x, y, fn _k, v1, v2 -> v2 ++ v1 end)
end)
Run Code Online (Sandbox Code Playgroud)
reduce 解决方案绝对是生产质量的答案。但是,由于您提到了函数式编程的困难,请考虑 reduce 的“长期”版本:
defmodule MapMerger do
# The api function takes a list of maps, and returns them merged together.
def merge(list_of_maps) do
# This is written with a second function to hopefully be easier to follow;
# these two functions could be collapsed using a default parameter
# for the accumulator.
do_merge(list_of_maps, %{})
end
# This is the base case, which will match after all maps have been processed
# and the list is empty:
defp do_merge([], acc), do: acc
# Next comes the actual iterator; we pull head (the first item in the list),
# process it, then recurse on the rest of the list and an updated accumulator
defp do_merge([head|rest], acc) do
updated_acc = Map.merge(acc, head)
do_merge(rest, updated_acc)
end
end
Run Code Online (Sandbox Code Playgroud)
一旦你能遵循这一点,reduce 应该更容易思考——它不会修改任何东西,它只是不断地递归新参数,这些新参数恰好是旧参数的更新版本。我的生产代码通常reduce用于这样的小工作,但是当reduce内部的操作很复杂时,我通常会将reduce分解为一个更容易推理、更容易用注释标记的适当函数。
从你原来的问题:
在其他语言中,我会定义一个空地图并遍历列表并填充地图
请注意,这是对上述merge和do_merge函数如何工作的合理描述。你并没有像你相信的那样远离功能性思考。
| 归档时间: |
|
| 查看次数: |
811 次 |
| 最近记录: |