2015-06-18 4 views

Antwort

78

Sie sollten die struct/2 Funktion verwenden. Aus der Dokumentation:

defmodule User do 
    defstruct name: "john" 
end 

struct(User) 
#=> %User{name: "john"} 

opts = [name: "meg"] 
user = struct(User, opts) 
#=> %User{name: "meg"} 

struct(user, unknown: "value") 
#=> %User{name: "meg"} 
+2

Wenn Sie Schlüssel haben erzwungen und sicherstellen, dass sie existieren in der Karte verwenden 'struct machen wollen!/2' statt. – RusinaRange

+1

Ich bin verwirrt. Diese Antwort zeigt die Initialisierung einer Struktur aus einer Schlüsselwortliste. Aber die Frage fragt nach Struktur von einer Karte. –

+1

Verstanden! "struct/2" funktioniert auch für eine Karte. Also, 'opts =% {name:" meg "}' funktioniert. –

22

Die bisherigen Antworten sind beide gut, mit einer caveat: Die Schlüssel in der Struktur sind Atome, die Schlüssel in Ihrem Hash könnten Strings sein. Die Methode struct() kopiert nur die übereinstimmenden Schlüssel und die Zeichenfolgen stimmen nicht mit den Atomen überein. Beispiel:

defmodule User do 
    defstruct name: "john" 
end 

opts = %{"name" => "meg"} 
user = struct(User, opts) 
#=> %User{name: "john"} 

verschmelzen Mit ungerade ist, auch, weil es "rückgängig machen", um die Struktur der Natur der Karte:

user = Map.merge(%User{}, opts) 
#=> %{:__struct__ => User, :name => "john", "name" => "meg"} 

Fand diese auf der Elixier-lang-Talk Google-Gruppe, von Jose selbst:

https://groups.google.com/d/msg/elixir-lang-talk/6geXOLUeIpI/L9einu4EEAAJ

, der ziemlich genau die Art und Weise ist zu gehen, außer dass Sie alles in einem Arbeitsgang tun:

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 
+1

Joses Antwort (und Ihre durch Abzug) sollte die akzeptierte sein, aus dem Grund, von Jose zu sein (Scherz). Die Verwendung der Zusammenführung hat mir Probleme bereitet, und ja, Sie verlieren vollständig die Strukturnatur. – sixFingers

+0

Danke dafür, ich brauchte einen ziemlich generischen Weg, um Strukturen aus allen Arten von Karten zu initialisieren und das war die Grundlage meines Hacks, um das https://github.com/chrisjowen/ExMapper zu machen – Owen

Verwandte Themen