How to sum similar values in a Map

I have an array of maps

[
  %{count_id: 103, value: 9.0},
  %{count_id: 200, value: 9.0},
  %{count_id: 99, value: 10.0}
]

I want to get a new array that sum(count_id) group by value. like this:

[
  %{count_id: 303, value: 9.0},
  %{count_id: 99, value: 10.0}
]

How to do that?

iex(4)> [                                                                                                                                     
...(4)>   %{count_id: 103, value: 9.0},
...(4)>   %{count_id: 200, value: 9.0},
...(4)>   %{count_id: 99, value: 10.0}
...(4)> ] |> Enum.group_by(& &1.value, & &1.count_id) |> Enum.map(fn {value, count_ids} -> %{value: value, count_id: Enum.sum(count_ids)} end)
[%{count_id: 303, value: 9.0}, %{count_id: 99, value: 10.0}]

3 Likes

Great!! Thanks

You can also use Enum.reduce/3

data = [                                                                                                                                     
  %{count_id: 103, value: 9.0},
  %{count_id: 200, value: 9.0},
  %{count_id: 99, value: 10.0}
]
|> Enum.reduce(%{}, fn %{count_id: id, value: value}, acc -> 
  Map.update(acc, value, id, &(&1 + id))
end)
|> Enum.map(fn {k, v} -> %{value: k, count_id: v} end)
3 Likes

This a nice and elegant solution. Thanks

Just for fun and to keep me in practice writing comprehensions

list = [
  %{count_id: 103, value: 9.0},
  %{count_id: 200, value: 9.0},
  %{count_id: 99, value: 10.0}
]

for {v, cids} <- Enum.group_by(list, & &1.value, & &1.count_id),
  do: %{count_id: Enum.sum(cids), value: v}
3 Likes