2015-06-18 9 views
52

मुझे %User{ email: '[email protected]' } के माध्यम से एक संरचना बनाने के लिए संभव है। लेकिन अगर मेरे पास एक चर params = %{email: '[email protected]'} है तो उस चर का उपयोग करके उस संरचना को बनाने का कोई तरीका है उदाहरण के लिए, %User{ params }एलिक्सीर में आप मानचित्र चर के साथ एक संरचना को कैसे प्रारंभ करते हैं

यह एक त्रुटि देता है, बस सोच रहा है कि क्या आप इसे या किसी अन्य तरीके से विस्फोट कर सकते हैं?

उत्तर

78

आपको struct/2 फ़ंक्शन का उपयोग करना चाहिए।

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

आप कुंजी लागू की और/2' के बजाय सुनिश्चित करें कि वे नक्शा उपयोग में मौजूद 'struct बनाने के लिए चाहते हैं! है। – RusinaRange

+1

मैं उलझन में हूँ। यह उत्तर किसी कीवर्ड सूची से संरचना के प्रारंभिकरण को दिखाता है। लेकिन सवाल एक मानचित्र से संरचना के बारे में पूछता है। –

+1

समझ गया! 'संरचना/2' मानचित्र के लिए भी काम करता है। तो, 'opts =% {name: "meg"}' काम करता है। –

14

Map.merge/2 का उपयोग कर इसे करने का एक और तरीका है: डॉक्स से

merge(map1, map2)

उदाहरण:

params 
#=> %{email: "[email protected]"} 

%User{} |> Map.merge(params) 
#=> %User{ email: '[email protected]' } 
+0

यदि आपके पास अपनी संरचना में enforced_keys है तो इस विधि का उपयोग नहीं किया जा सकता है। जोस (मजाक) से होने के कारण – RusinaRange

22

पिछले जवाब दोनों अच्छे हैं, एक के साथ चेतावनी: संरचना में चाबियाँ परमाणु हैं, आपके हैश में चाबियाँ तार हो सकती हैं। संरचना() विधि का उपयोग केवल मिलान की जाने वाली कुंजियों पर प्रतिलिपि करेगा, और तार परमाणुओं से मेल नहीं खाएंगे। उदाहरण:

defmodule User do 
    defstruct name: "john" 
end 

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

मर्ज का उपयोग करना भी अजीब है, क्योंकि यह "पूर्ववत करें" होगा मानचित्र की struct प्रकृति:

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

अमृत-लैंग बात Google समूह पर यह पाया जाता है, जोस से खुद को:

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

कि काफी छोड़कर आप एक पास में सब कुछ कर सकते हैं जाने के लिए रास्ता नहीं है:

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

जोस का जवाब (और कटौती द्वारा आपका) स्वीकार किया जाना चाहिए। विलय का उपयोग करने से मुझे समस्याएं आईं, और हां, आप पूरी तरह से संरचना प्रकृति को खो देते हैं। – sixFingers

+0

इसके लिए धन्यवाद, मुझे सभी प्रकार के मानचित्रों से structs शुरू करने के लिए एक बहुत ही सामान्य तरीका चाहिए और यह मेरे हैक का आधार यह है https://github.com/chrisjowen/ExMapper – Owen

संबंधित मुद्दे

 संबंधित मुद्दे