使用来自另一个地图 (Elixir) 的值更新地图中的所有值

Update all values in a map using values from another map (Elixir)

如何使用来自另一个地图的相应键的值更新地图中的所有值? 例如,我有以下两张地图:

map = %{"December 2021" => 0, "November 2021" => 0, "October 2021" => 0}
map_2 = %{"December 2021" => 7, "November 2021" => 6}

我想用 map_2 中的相应值更新地图中的所有值,所以最后 map = %{"December 2021" => 7, "November 2021" => 6, " 2021 年 10 月" => 0}

我试过:

Enum.map(map_2, fn {key, value} -> %{map | k => v} end)

我也尝试过将上面的代码与 Map.update!/3 等其他函数和类似函数一起使用,但它们都是 return 一个列表,其中包含 Enum.map 的每次迭代的映射。

有人知道怎么做吗?

提前致谢

我认为您正在寻找 Enum.reduce/3。这里的reduce是指将一个集合缩减为一个值。这里要减少的集合是map_2。您开始的 initial/single 值是原始集合 map。输出是对初始值的修改。

在这个例子中,map_2 的每个 key/value 都被传递给一个函数,该函数也需要一个累加器 accacc 初始化为初始值 map(Enum.reduce 的第二个参数)。在这种情况下,map_2 的每个值都添加到 map:

map = %{"December 2021" => 0, "November 2021" => 0, "October 2021" => 0}
map_2 = %{"December 2021" => 7, "November 2021" => 6}

Enum.reduce(map_2, map, fn {key, value}, acc ->
  Map.put(acc, key, value)
end)

#> %{"December 2021" => 7, "November 2021" => 6, "October 2021" => 0}

如果您想要不同的行为,例如不要使用 map 中不存在的键添加来自 map_2 的值:尝试更改 reducer 函数。

完成此操作最惯用的方法是使用 Map.merge/2 函数,它的作用恰恰是:

Map.merge(map, map_2)

这会将 map_2 中的所有键值对合并到 map

当然,您可以使用 Enum.reduce/3 以及 @zwippie 的建议来编写它的自定义版本,但这会降低效率并且更加冗长。