Elixir的“Kernel.delete_in”等价吗?

时间:2017-08-04 01:49:59

标签: elixir

Elixir的Kernel.put_in非常适合在嵌套结构中添加或更新深层值。但是,它不支持删除该值,我在任何地方都看不到~/saved.txt

是否存在delete_indelete_in或某些等效内容?像

这样的东西
pop_in

没有它,添加和更新功能看起来就像很好的管道,但删除或弹出功能看起来不那么整洁。

2 个答案:

答案 0 :(得分:2)

是的,Kernel.pop_in/1Kernel.pop_in/2存在,它们返回已删除的值和数据值,而没有我们刚刚删除的键/路径。

iex(1)> data = %{1 => %{2 => %{3 => 4, 5 => 6}}}
%{1 => %{2 => %{3 => 4, 5 => 6}}}
iex(2)> pop_in(data, [1, 2, 5])
{6, %{1 => %{2 => %{3 => 4}}}}
iex(3)> pop_in(data[1][2][5])
{6, %{1 => %{2 => %{3 => 4}}}}

要仅获取没有弹出值的数据,您可以使用模式匹配或|> elem(1)

iex(4)> pop_in(data, [1, 2, 5]) |> elem(1)
%{1 => %{2 => %{3 => 4}}}
iex(5)> pop_in(data[1][2][5]) |> elem(1)
%{1 => %{2 => %{3 => 4}}}

答案 1 :(得分:1)

!根据文档,Kernel.get_and_update_in/3将函数作为第三个参数

  

必须返回一个双元素元组:“get”值(检索到的值,   可以在返回之前进行操作)和新值   存储在密钥下。 乐趣也可能会回归:pop ,意味着当前   值应从结构中删除并返回。

所以delete_in可以写成

def delete_in(data, keys) do
  {_val, data} = get_and_update_in(data, keys, fn key -> :pop end)
  data
end

或者可以直接在管道中使用get_and_update_in/3,例如

data
|> get_and_update(keys, fn key -> :pop end)
|> elem(1)