在Elixir的结构中删除nil值的好方法是什么?

Ton*_*Han 11 elixir

例如,我有一个结构

post = %Post{title: "Title", desc: nil}
Run Code Online (Sandbox Code Playgroud)

我想得到

%{title: "Title"}
Run Code Online (Sandbox Code Playgroud)

我的解决方案就像

post
  |> Map.delete(:__struct__) # change the struct to a Map
  |> Enum.filter(fn {_, v} -> v end)
  |> Enum.into(%{})
Run Code Online (Sandbox Code Playgroud)

它有效,但有更好的吗?

更新:

我觉得很烦人从Struct转换为Map,然后是Enum,然后再转换Map.有简洁的方法吗?

hah*_*g65 23

而不是做

post
  |> Map.delete(:__struct__) # change the struct to a Map
  |> Enum.filter(fn {_, v} -> v end)
  |> Enum.into(%{})
Run Code Online (Sandbox Code Playgroud)

你可以做

post
  |> Map.from_struct
  |> Enum.filter(fn {_, v} -> v != nil end)
  |> Enum.into(%{})
Run Code Online (Sandbox Code Playgroud)

它比__struct__手动删除密钥要简单一些.

  • 您应该将第二个示例中的过滤更改为"v!= nil"或使用"reject"而不是"filter". (3认同)

chr*_*mcg 18

您也可以通过理解来做到这一点:

for {k, v} <- Map.from_struct(post), v != nil, into: %{}, do: {k, v}
Run Code Online (Sandbox Code Playgroud)


ove*_*uka 7

也可以这样写:

post
    |> Map.from_struct
    |> Enum.reject(fn {_, v} -> is_nil(v) end)
    |> Map.new
Run Code Online (Sandbox Code Playgroud)