合并更新值的地图列表

时间:2017-06-05 17:12:46

标签: elixir

我正在尝试合并一个词典列表。列表中的每个字典都是嵌套的,我需要对列表中的每个元素求和。例如;

samples = [
  %{team1: %{a: 5, f: 0, n_games: 1}, team2: %{a: 0, f: 2, n_games: 1}},
  %{team1: %{a: 1, f: 2, n_games: 1}, team2: %{a: 4, f: 3, n_games: 1}}
]

需要返回

%{team1: %{a: 6, f: 2, n_games: 2}, team2: %{a: 4, f: 5, n_games: 2}}

我很乐意分享我所拥有的任何代码,但老实说我没有什么可分享的,因为我不知道在Elixir中遇到这类问题的方法。

1 个答案:

答案 0 :(得分:2)

您可以使用Enum.reduce/2Map.merge/3的组合。在Map.merge/3中,回调应该添加两个值的三个字段。

samples = [
  %{team1: %{a: 5, f: 0, n_games: 1}, team2: %{a: 0, f: 2, n_games: 1}},
  %{team1: %{a: 1, f: 2, n_games: 1}, team2: %{a: 4, f: 3, n_games: 1}}
]

samples
|> Enum.reduce(fn x, acc ->
  Map.merge(x, acc, fn _key, %{a: a1, f: f1, n_games: ng1}, %{a: a2, f: f2, n_games: ng2} ->
    %{a: a1 + a2, f: f1 + f2, n_games: ng1 + ng2}
  end)
end)
|> IO.inspect

输出:

%{team1: %{a: 6, f: 2, n_games: 2}, team2: %{a: 4, f: 5, n_games: 2}}

如果您不想对地图中的键列表进行硬编码,只想添加所有值,则可以改为:

|> Enum.reduce(fn x, acc ->
  Map.merge(x, acc, fn _key, map1, map2 ->
    for {k, v1} <- map1, into: %{}, do: {k, v1 + map2[k]}
  end)
end)