汇总值的地图列表

Jod*_*oro 1 elixir

我有这个:

a1 = [%{id: 1, val: 12}, %{id: 3, val: 7}, %{id: 1, val: 5}, %{id: 2, val: 3}, %{id: 2, val: 5}], %{id: 1, val: 3}]
Run Code Online (Sandbox Code Playgroud)

我怎么能得到这个?

%{
    1 => 20,
    2 => 8,
    3 => 7
  }
Run Code Online (Sandbox Code Playgroud)

也就是说,按"id"分组的每个项目的"val"之和

我应该先用"id"将它们分组吗?

Enum.group_by a1, &(&1.id)

  # =>

  %{
    1 => [%{id: 1, val: 12}, %{id: 1, val: 3}, %{id: 1, val: 5}],
    2 => [%{id: 2, val: 3}, %{id: 2, val: 5}],
    3 => [%{id: 3, val: 7}]
  }
Run Code Online (Sandbox Code Playgroud)

然后做mapreduce在每个项目上?或者,还有更好的方法?

Dog*_*ert 7

我这样做,只需一个Enum.reduce/3电话:

[%{id: 1, val: 12}, %{id: 3, val: 7}, %{id: 1, val: 5}, %{id: 2, val: 3}, %{id: 2, val: 5}, %{id: 1, val: 3}]
|> Enum.reduce(%{}, fn %{id: id, val: val}, map ->
  Map.update(map, id, val, &(&1 + val))
end)
|> IO.inspect
Run Code Online (Sandbox Code Playgroud)

输出:

%{1 => 20, 2 => 8, 3 => 7}
Run Code Online (Sandbox Code Playgroud)

这应该比group_by+ map+ 更有效reduce.