2015-01-30 7 views
7

मैं इलीक्सिर के लिए नया हूं और अभी भी पैटर्न मिलान के साथ बहुत उलझन में हूं।नेस्टेड डेटा संरचना में फ़िल्टरिंग/पैटर्न मिलान

[%{name: "Deutschland", code: "DE"}, %{name: "Frankreich", code: "FR"}]

def find_by_code([], _name), do: [] 
    def find_by_code([h | t], query) do 
    if h[:code] == query do 
     IO.puts("MATCH") 
     IO.inspect(h) 
    else 
     IO.puts ("No match") 
     find_by_code(t, query) 
    end 
    end 

कि सबसे अच्छा तरीका है कोड से देश को खोजने के लिए है?

उत्तर

9

आप कर सकते हैं पैटर्न मैच के रूप में गहरे रूप में आप चाहते:

def find_by_code([], _query), 
    do: nil # or whatever you want to mean "not found" 

def find_by_code([%{code: query} = country|_t], query), 
    do: IO.inspect(country) 

def find_by_code([_country|t], query), 
    do: find_by_code(t, query) 

तुम भी match?/2 साथ Enum.find/3 उपयोग कर सकते हैं, (के रूप में एक और जवाब में सुझाव दिया) अधिक पठनीय हो सकता है।

+0

यह एक अच्छा जवाब है, यह भी पता नहीं था कि दूसरा फॉर्म संभव था! – greggreg

+0

ग्रेट उत्तर, एक छोटा सा अतिरिक्त जो चेतावनी से छुटकारा पायेगा। दूसरे फ़ंक्शन क्लॉज में 't' चर का उपयोग नहीं किया जाता है और इसलिए इसे' _t' के रूप में निर्दिष्ट किया जाना चाहिए। – b73

+0

@ बी 73 अच्छा पकड़ो! मैंने लिखा कि मोबाइल पर मैंने इसे भी नहीं चलाया, ओह :) धन्यवाद! – whatyouhide

7

आप इसे इस तरह से कर सकता है:

countries = [ 
    %{name: "Deutschland", code: "DE"}, 
    %{name: "Frankreich", code: "FR"} 
] 

Enum.find(countries, &match?(%{code: "FR"}, &1)) 
# %{code: "FR", name: "Frankreich"} 
+1

'मैच?/2' मैक्रो ** अच्छा ** है! मुझे नहीं पता कि मुझे इसके बारे में कैसे पता नहीं था। धन्यवाद पैट्रिक! – whatyouhide

+1

हां, जब मैं इसके बारे में भी पता चला तो मैं वास्तव में उत्साहित था! ऐसा करने के लिए मैंने पहले [मैक्रो लिखा था] (https://gist.github.com/padde/a759b18bca7851e8ffaa)। फिर भी, यह मेरा पहला मैक्रो था और मैंने प्रक्रिया में बहुत कुछ सीखा ;-) –

2

अमृत उनके मूल्यों पर आधारित सूची के कुछ आइटमों को फ़िल्टर करने की कोशिश कर के लिए मिलान पैटर्न में निर्माण किया है नहीं है।

तुम इतनी तरह अलग-अलग आइटम की जाँच करने के एक पैटर्न मैच लिख सकते हैं:

match_country_code = fn (%{:code => "DE"} = country) -> country 
         (_) -> nil 
        end 

और फिर Enum.find है कि पारित:

lands = [ 
    %{name: "Deutschland", code: "DE"}, 
    %{name: "Frankreich", code: "FR"} 
] 
Enum.find(lands, &(match_country_code.(&1))) 
# => %{code: "DE", name: "Deutschland"} 

या सामान्यीकरण करने के लिए आप:

lands = [ 
    %{name: "Deutschland", code: "DE"}, 
    %{name: "Frankreich", code: "FR"} 
] 

find_by = fn (list, key, val) -> 
    Enum.find(list, &(Map.get(&1, key)==val)) 
end 

find_by.(lands, :name, "DE") 
#=> %{code: "DE", name: "Deutschland"} 

फ़िल्टर करने के लिए खोजें और परिणामों की एक सूची प्राप्त करें:

lands = [ 
    %{name: "Deutschland", code: "DE"}, 
    %{name: "Germany", code: "DE"}, 
    %{name: "Frankreich", code: "FR"} 
] 

filter_by = fn (list, key, val) -> 
    Enum.filter(list, &(Map.get(&1, key)==val)) 
end 

filter_by.(lands, :code, "DE") 
#=> [%{code: "DE", name: "Deutschland"}, %{code: "DE", name: "Germany"}] 
संबंधित मुद्दे