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

What's a good solution to drop nil value in a struct for Elixir?

比如我有一个结构体

post = %Post{title: "Title", desc: nil}

我想得到

%{title: "Title"}

我的解决方案是

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

可以用,但有更好的吗?

更新:

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

而不是

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

你可以做到

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

它只是比手动删除 __struct__ 键稍微干净一些。

你也可以用推导来做到这一点:

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

也可以这样写:

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

另一种选择是:

post
  |> Map.from_struct()
  |> Enum.filter(fn {_key, value} -> !is_nil(value) end)
  |> Map.new()

Map.new/1被认为正是将关键字列表转换为地图。