如何在Elixir中映射和缩小地图列表

时间:2016-10-20 04:06:27

标签: functional-programming elixir phoenix-framework

映射和缩小灵药列表并将其转换为新列表的好方法是什么。

要求: 1.找到具有相同ID的地图: 2.合并“角色”键的值(即收集所有唯一值)。 3.对于所有其他地图(列表元素),不执行任何操作。

list = [%{"id": 1, "role": ["A", "B"]}, %{"id": 2, "role": ["B", "C"]}, %{"id": 1, "role": ["C", "A"]} ]
需要在以下列表中转换

ans_list = [%{"id": 1, "role": ["A", "B", "C"]}, %{"id": 2, "role": ["B", "C"]}]

1 个答案:

答案 0 :(得分:3)

您可以使用Enum.group_by/2id进行分组,然后针对每个群组,将role传递给Enum.flat_map/2Enum.uniq/1

list = [%{"id": 1, "role": ["A", "B"]}, %{"id": 2, "role": ["B", "C"]}, %{"id": 1, "role": ["C", "A"]} ]

list
|> Enum.group_by(&(&1.id))
|> Enum.map(fn {key, value} ->
  %{id: key, role: value |> Enum.flat_map(&(&1.role)) |> Enum.uniq}
end)
|> IO.inspect

输出:

[%{id: 1, role: ["A", "B", "C"]}, %{id: 2, role: ["B", "C"]}]

根据以下评论的要求,以下是如何保留所有键/值对,并仅修改组中第一项的role

list =  [%{"id": 1, "role": ["A", "B"], "somekey": "value of the key 1"},
         %{"id": 2, "role": ["B", "C"], "somekey": "value of the key 2"},
         %{"id": 1, "role": ["C", "A"], "somekey": "value of the key 3"}]

list
|> Enum.group_by(&(&1.id))
|> Enum.map(fn {_, [value | _] = values} ->
  %{value | role: values |> Enum.flat_map(&(&1.role)) |> Enum.uniq}
end)
|> IO.inspect

输出:

[%{id: 1, role: ["A", "B", "C"], somekey: "value of the key 1"},
 %{id: 2, role: ["B", "C"], somekey: "value of the key 2"}]