在Elixir中按多个值映射组
我有这张地图在Elixir中按多个值映射组,elixir,Elixir,我有这张地图 map = [ %{id: 2, brand: "TUTU", reference: "1234"}, %{id: 2, brand: "TUTU", reference: "4567"}, %{id: 3, brand: "TOTO", reference: "789456"} ] 我想按ID进行分组,得到如下结果: [ %{ id:
map = [
%{id: 2, brand: "TUTU", reference: "1234"},
%{id: 2, brand: "TUTU", reference: "4567"},
%{id: 3, brand: "TOTO", reference: "789456"}
]
我想按ID进行分组,得到如下结果:
[
%{
id: 2,
brand: "TUTU",
reference: [
"1234",
"5845"
]
},
%{
id: 3,
brand: "TOTO",
reference: [
"4587"
]
}
]
我尝试像这样使用Enum.group_
map
|> Enum.group_by(fn entry -> entry.brand end)
但结果是这样的:
%{
"TOTO" => [%{brand: "TOTO", id: 3, reference: "789456"}],
"TUTU" => [
%{brand: "TUTU", id: 2, reference: "1234"},
%{brand: "TUTU", id: 2, reference: "4567"}
]
}
我觉得我很接近解决方案,但我不知道如何将我的信息重新组合到列表中,而不是使用键作为索引
抱歉,我不是很清楚,我只是不知道如何描述我的问题如果您不需要特别注意检测不需要分组的密钥,只需提前列出它们,那么像这样的嵌套Enum.map将满足您的需要:
data = [
%{id: 2, brand: "TUTU", reference: "1234"},
%{id: 2, brand: "TUTU", reference: "4567"},
%{id: 2, brand: "TOTO", reference: "4567"},
%{id: 3, brand: "TOTO", reference: "789456"}
]
keys_to_group_by = [:id, :brand]
keys_to_list = [:reference]
data
|> Enum.group_by(&Map.take(&1, keys_to_group_by))
|> Enum.map(fn {key, values} ->
keys_to_list
|> Enum.map(fn key_to_list ->
{key_to_list, Enum.map(values, & &1[key_to_list])}
end)
|> Enum.into(key)
end)
请注意|>Enum.group_by&Map.take&1,keys_to_group_by-这是通过多个键进行分组的部分,因此%{id:2,brand:TOTO}和%{id:2,brand:tututu}最终位于不同的存储桶中。您还可以查看和而不是简单的Enum.group_by/2,这样您就不必再将分组的条目映射到仅引用中
map
|> Enum.reduce(%{}, &group_by_brand/2)
|> Enum.map(&to_map/1)
...
defp group_by_brand(entry, acc) do
Map.update(acc, {entry.id, entry.brand}, [entry.reference], &[entry.reference | &1])
end
defp to_map({{id, brand}, references}) do
%{id: id, brand: brand, references: references}
end
另一种可能是直接进入所需结构,包括: 数据 |>Enum.reduce%{},fn%{id:id,brand:brand,reference:ref},acc-> 更新[u inacc,[{id,brand}],fn nil->%{id:id,brand:brand,ref:[ref]} refs->%{refs | reference:[ref | refs.reference]} 终止 终止 |>映射值