所以嵌套的地图无法直接更新,我们必须使用put_in。例如:
iex(1)> m = %{a: %{b: 1}}
%{a: %{b: 1}}
iex(2)> m[:a][:b]
1
iex(3)> m[:a][:b] = 2
** (CompileError) iex:3: cannot invoke remote function Access.get/2 inside match
(stdlib) lists.erl:1354: :lists.mapfoldl/3
iex(3)> m = put_in m, [:a, :b], 2
%{a: %{b: 2}}
但如果m看起来像这样,我想将元素2添加到叶节点 list (而不是map):
iex(7)> m = %{a: %{b: [1]}}
%{a: %{b: [1]}}
iex(8)> put_in m, [:a, :b], 2
%{a: %{b: 2}}
iex(9)>
所以put_in(逻辑上)用值2替换列表,而不是在列表中添加2。我想要的是这个结果:
%{a: %{b: [1, 2]}}
这是update_in进来的地方吗?我该怎么做?
同样,如果叶节点是MapSet,我该怎么做?
答案 0 :(得分:1)
是的,你想在这里update_in
:
iex(1)> m = %{a: %{b: [1]}}
%{a: %{b: [1]}}
iex(2)> update_in m, [:a, :b], &(&1 ++ [2])
%{a: %{b: [1, 2]}}
对于MapSet
,您需要使用MapSet.put/2
代替++
:
iex(3)> m = %{a: %{b: MapSet.new([1])}}
%{a: %{b: #MapSet<[1]>}}
iex(4)> update_in m, [:a, :b], &MapSet.put(&1, 2)
%{a: %{b: #MapSet<[1, 2]>}}