Elixir convert struct to map

DictionaryStructElixirTelegram Bot

Dictionary Problem Overview


I'm trying to convert a struct to a map to be able to clean all the nil values

I'm currently using this code

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

Note: Nadia.get_updates returns the following structure: https://hexdocs.pm/nadia/Nadia.Model.Update.html#t:t/0

Yet I'm always receiving the following error: no function clause matching in Map.from_struct/1

Dictionary Solutions


Solution 1 - Dictionary

Since v0.15 we have Map.from_struct/1 which does exactly this.

defmodule User do
  defstruct [:name]
end

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

Solution 2 - Dictionary

There's another trick

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

Solution 3 - Dictionary

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

If successful it returns a list of Nadia.Model.Update.t. That's why you get that error.

Solution 4 - Dictionary

FWIW, I wrote a library that will do this kind of thing for you automagically w/o having to pull the data structure apart.

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

This is from the test code:

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

Note, if data was a list of maps this would still work just fine. The PhStTransform library will just keep pulling the data apart until it finds a map. In your case you would use a replace_nil function that worked on the kinds of structs you are interested in.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2070502View Question on Stackoverflow
Solution 1 - DictionaryJulianoView Answer on Stackoverflow
Solution 2 - DictionaryradzsergView Answer on Stackoverflow
Solution 3 - DictionarySasha FonsecaView Answer on Stackoverflow
Solution 4 - DictionaryFred the Magic Wonder DogView Answer on Stackoverflow