2016-04-09 25 views
14

Sto cercando di convertire una struct a una mappa per essere in grado di pulire tutti i valori nulliElixir convertito struct per mappare

Attualmente sto usando questo codice

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

Nota: Nadia. get_updates restituisce la seguente struttura: https://hexdocs.pm/nadia/Nadia.Model.Update.html#t:t/0

Eppure io sono sempre riceve il seguente errore: nessuna clausola funzione di corrispondenza in Map.from_struct/1

+5

Forse 'results' è un elenco di queste strutture? Non solo una struttura? – JustMichael

risposta

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

In caso di successo, restituisce un elenco di Nadia.Model.Update.t. Ecco perché ottieni questo errore.

1

FWIW, Ho scritto una libreria che farà questo genere di cose per te automaticamente senza dover separare la struttura dei dati.

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

Questo è dal codice di prova:

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 

nota, se i dati è stato un elenco di mappe questo sarebbe ancora funzionare bene. La libreria PhStTransform continuerà a separare i dati finché non troverà una mappa. Nel tuo caso si usa una funzione replace_nil che ha lavorato sul tipo di struct a cui è interessato.

6

C'è un altro trucco

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

Dal v0.15 abbiamo Map.from_struct/1 che fa esattamente questo.

defmodule User do 
    defstruct [:name] 
end 

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