映射和缩小灵药列表并将其转换为新列表的好方法是什么。
要求: 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"]}]
答案 0 :(得分:3)
您可以使用Enum.group_by/2
按id
进行分组,然后针对每个群组,将role
传递给Enum.flat_map/2
和Enum.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"}]