Elixir:有什么更好的方法来迭代并从这个嵌套列表中收集值?

时间:2017-06-15 04:43:36

标签: elixir

我想从所有人那里得到总数和失败的比赛。下面的代码有效,但我认为它不是很好。有更好的,更多的Elixir方式吗?

person_races = %{
"joy" => %{ "medals" => [%{ "race" => "finished"}, %{"race" => 
"finished"}, %{"race" => "failed"}]},
"jan" => %{ "medals" => [%{ "race" => "finished"}, %{"race" => 
"finished"}, %{"race" => "failed"}]},
"jim" => %{ "medals" => [%{ "race" => "finished"}, %{"race" => 
"finished"}, %{"race" => "failed"}]},
}

answer = Enum.reduce(person_races, [], fn({_k,v}, acc) -> 
  acc ++ [v]
end)
|> Enum.reduce([], fn(x, acc) ->
  acc ++ x["medals"]
end)
|> Enum.reduce(%{}, fn(k, acc) ->
    cond do
      k["race"] == "failed" ->
        Map.update(acc, :failed, 1, &(&1 + 1))
      k["race"] == "finished" ->
        Map.update(acc, :finished, 1, &(&1 + 1))
    end
end)

IO.inspect answer #=> %{failed: 3, finished: 6}

1 个答案:

答案 0 :(得分:3)

您可以将其实现为管道:

person_races 
|> Map.values() 
|> Enum.flat_map(&Map.get(&1, "medals")) 
|> Enum.map(&Map.get(&1, "race")) 
|> Enum.reduce(%{}, fn x, acc -> Map.update(acc, x, 1, & &1 + 1) end)

%{"failed" => 3, "finished" => 6}