Elixir将struct转换为map

时间:2016-04-09 04:04:15

标签: dictionary struct elixir telegram-bot

我正在尝试将结构转换为地图,以便能够清除所有的零值

我目前正在使用此代码

  case Nadia.get_updates  do
    {:ok, results} ->
      Map.from_struct(results)
      |> Enum.filter(fn {_, v} -> v != nil end)
      |> Enum.into(%{})

注意:Nadia.get_updates返回以下结构: https://hexdocs.pm/nadia/Nadia.Model.Update.html#t:t/0

然而,我总是收到以下错误:Map.from_struct / 1中没有匹配的函数子句

4 个答案:

答案 0 :(得分:39)

v0.15以来,我们Map.from_struct/1就是这样做了。

defmodule User do
  defstruct [:name]
end

Map.from_struct(%User{name: "valim"})
#=> %{name: "valim"}

答案 1 :(得分:10)

还有另一个技巧

{{1}}

答案 2 :(得分:2)

get_updates([{atom, any}]) ::
  {:ok, [Nadia.Model.Update.t]} |
  {:error, Nadia.Model.Error.t}

如果成功,则返回Nadia.Model.Update.t列表。这就是你得到这个错误的原因。

答案 3 :(得分:1)

FWIW,我写了一个库,可以自动完成这种事情,而不必将数据结构分开。

https://github.com/philosophers-stone/transform

这是来自测试代码:

test "implement scrub of empty values from map" do
  data = %{ :a => nil, :b => "", :c => "a"}
  replace_empty = fn(string, _d) -> if( string == "", do: nil , else: string) end
  replace_nil = fn(map, _depth) ->  for {k, v} <- map, v != nil , into: %{}, do: {k, v} end
  potion = %{ BitString => replace_empty, Map => replace_nil}

  assert PhStTransform.transform(data, potion) == %{:c => "a"}

end

注意,如果数据是地图列表,那么这仍然可以正常工作。 PhStTransform库将继续将数据拉开,直到找到一张地图。在您的情况下,您将使用replace_nil函数,该函数处理您感兴趣的结构类型。