Эликсир преобразует структуру в карту

Я пытаюсь преобразовать структуру в карту, чтобы иметь возможность очистить все значения nil

Я сейчас использую этот код

  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

Ответы

Ответ 1

Так как v0.15, то Map.from_struct/1 выполняет именно это.

defmodule User do
  defstruct [:name]
end

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

Ответ 2

Там другой трюк

my_struct = %MyStruct{}
my_map = Map.delete my_struct, :__struct__

Ответ 3

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

В случае успеха возвращает список Nadia.Model.Update.t. Вот почему вы получаете эту ошибку.

Ответ 4

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, которая работала над типами структур, которые вас интересуют.