如何在Elixir中映射和减少地图列表 [英] How to map and reduce List of Maps in Elixir

查看:106
本文介绍了如何在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]}] 


解决方案可以使用< id ,然后为每个组传递角色 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆