Le risposte precedenti sono entrambi buoni, con uno avvertenza: le chiavi nella struttura sono atomi, le chiavi nel tuo hash potrebbero essere stringhe. L'utilizzo del metodo struct() copia solo le chiavi corrispondenti, e le stringhe non corrispondono agli atomi. Esempio:
defmodule User do
defstruct name: "john"
end
opts = %{"name" => "meg"}
user = struct(User, opts)
#=> %User{name: "john"}
Utilizzando merge è strano, troppo, perché sarà "annullare" la natura struct della Mappa:
user = Map.merge(%User{}, opts)
#=> %{:__struct__ => User, :name => "john", "name" => "meg"}
trovato questo sul elisir-lang-talk Google Group, da Jose stesso:
https://groups.google.com/d/msg/elixir-lang-talk/6geXOLUeIpI/L9einu4EEAAJ
che è praticamente la strada da percorrere ad eccezione si può fare tutto in un solo passaggio:
def to_struct(kind, attrs) do
struct = struct(kind)
Enum.reduce Map.to_list(struct), struct, fn {k, _}, acc ->
case Map.fetch(attrs, Atom.to_string(k)) do
{:ok, v} -> %{acc | k => v}
:error -> acc
end
end
end
Se si è imposto chiavi e vuole fare in modo che esistono nell'uso mappa 'struct!/2' invece. – RusinaRange
Sono confuso. Questa risposta mostra l'inizializzazione di una struttura da un elenco di parole chiave. Ma la domanda si interroga su struct da una mappa. –
Trovato! 'struct/2' funziona anche per una mappa. Quindi, 'opts =% {name:" meg "}' funziona. –