Если исходный список хранится в локальной переменной input
, можно начать с Enum.reduce/3
, используя Map.update/4
в качестве редуктора.
Enum.reduce(input, %{}, fn %{score: score, name: name}, acc ->
Map.update(acc, name, score, & &1 + score)
end)
#⇒ %{"Elixir" => 12, "Javascript" => 1}
Если вы настаиваете на наличии списка карт в результате (который IMSO гораздо менее читабелен), go далее и Enum.map/2
результат:
Enum.map(%{"Elixir" => 12, "Javascript" => 1}, fn {name, score} ->
%{name: name, score: score}
end)
#⇒ [%{name: "Elixir", score: 12},
# %{name: "Javascript", score: 1}]
Подводя итог:
input
|> Enum.reduce(%{}, fn %{score: score, name: name}, acc ->
Map.update(acc, name, score, & &1 + score)
end)
|> Enum.map(& %{name: elem(&1, 0), score: elem(&1, 1)})
#⇒ [%{name: "Elixir", score: 12},
# %{name: "Javascript", score: 1}]
Sidenote: карты в erlang (и, следовательно, в эликсир ) не заказан . Это означает, что если вы хотите, чтобы результирующий список был отсортирован по name
или score
, вам следует явно Enum.sort/2
it:
Enum.sort(..., & &1.score > &2.score)
#⇒ [%{name: "Elixir", score: 12},
# %{name: "Javascript", score: 1}]