我有什么:
%{1 => #MapSet<[123, 234, 345, 456, 567]>,
2 => #MapSet<[345, 456, 567, 678, 789]>}
我需要什么:
%{123 => #MapSet<[1],
234 => #MapSet<[1],
345 => #MapSet<[1,2],
456 => #MapSet<[1,2],
567 => #MapSet<[1,2],
678 => #MapSet<[2],
789 => #MapSet<[2]}
我似乎无法在长生不老药中找到这样的功能,而我写自己的尝试并不顺利。
编辑:
我最终将此作为我的最终解决方案:
Enum.reduce(x, %{}, fn {k, vs}, acc ->
Enum.reduce(vs, acc, fn v, acc ->
update_in(acc[v], fn
nil -> MapSet.new([k])
set -> set |> MapSet.put(k)
end)
end)
end)
答案 0 :(得分:2)
您可以在此处使用嵌套Enum.reduce/3
:
map = %{1 => MapSet.new([123, 234, 345, 456, 567]),
2 => MapSet.new([345, 456, 567, 678, 789])}
Enum.reduce(map, %{}, fn {k, vs}, acc ->
Enum.reduce(vs, acc, fn v, acc ->
Map.update(acc, v, MapSet.new([k]), &MapSet.put(&1, k))
end)
end)
|> IO.inspect
输出:
%{123 => #MapSet<[1]>, 234 => #MapSet<[1]>, 345 => #MapSet<[1, 2]>,
456 => #MapSet<[1, 2]>, 567 => #MapSet<[1, 2]>, 678 => #MapSet<[2]>,
789 => #MapSet<[2]>}
这可能会稍快一些,因为如果密钥已经存在,它不会创建MapSet:
Enum.reduce(map, %{}, fn {k, vs}, acc ->
Enum.reduce(vs, acc, fn v, acc ->
set = if set = Map.get(acc, v), do: MapSet.put(set, k), else: MapSet.new([k])
Map.put(acc, v, set)
end)
end)
|> IO.inspect
答案 1 :(得分:2)
我会发布@Dogbert稍微修改后的答案,该答案会使用更多惯用Map.get_and_update/3
和Kernel.SpecialForms.with/1
:
map = %{1 => MapSet.new([123, 234, 345, 456, 567]),
2 => MapSet.new([345, 456, 567, 678, 789])}
Enum.reduce(map, %{}, fn {k, vs}, acc ->
Enum.reduce(vs, acc, fn v, acc ->
with {_, map} <- Map.get_and_update(acc, v, fn
nil -> {nil, MapSet.new([k])}
set -> {set, MapSet.put(set, k)}
end), do: map
end)
end)
|> IO.inspect