如何在Elixir中映射和减少地图列表 [英] How to map and reduce List of Maps in Elixir
问题描述
要求:
1.查找具有相同ID的地图:
2.合并角色键的值(即收集所有唯一值)。
3.对于所有其他地图(列表元素),什么也不做。
list = [%{id :1,角色:[A,B]},%{id:2,role:[B,C]},%{id 角色:[C,A]}]
需要在以下列表:
ans_list = [%{id:1,role:[A,B ,C]},%{id:2,role:[B,C]}]
角色
到 Enum.flat_map / 2
以及 Enum.uniq / 1
: list = [%{id :1,role:[A,B]},%{id:2,role:[B,C]},%{id 角色:[C,A]}]
列表
|> 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]} ]
正如下面的评论所要求的,保留所有键/值对,只修改组中第一项的角色
:
list = [%{id:1,role:[A,B],somekey:key 1的值},
%{ id:2,role:[B,C],somekey:key 2的值},
%{id:1,role:[ C,A],somekey: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
输出:
<$ p $
%{id:1,role:[A,B,C],somekey:key 1的值},
%{id: 2,role:[B,C],somekey:key 2的值}]
What's a good way to map and reduce the elixir's list and convert it into new list.
Requirement: 1. Find the maps with same id: 2. Merge the values of "role" key (i.e. Gather all the unique values). 3. For all other maps(elements of list), do nothing.
list = [%{"id": 1, "role": ["A", "B"]}, %{"id": 2, "role": ["B", "C"]}, %{"id": 1, "role": ["C", "A"]} ]
needs to be converted in the following list:
ans_list = [%{"id": 1, "role": ["A", "B", "C"]}, %{"id": 2, "role": ["B", "C"]}]
You can use Enum.group_by/2
to group by the id
, then for each group, pass the role
to Enum.flat_map/2
and 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
Output:
[%{id: 1, role: ["A", "B", "C"]}, %{id: 2, role: ["B", "C"]}]
As requested in a comment below, here's how to preserve all key/value pairs and only modify role
of the first item of a group:
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
Output:
[%{id: 1, role: ["A", "B", "C"], somekey: "value of the key 1"},
%{id: 2, role: ["B", "C"], somekey: "value of the key 2"}]
这篇关于如何在Elixir中映射和减少地图列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!