Filtering / matching patterns in a nested data structure

I am new to Elixir and am still very confused about pattern matching.

[%{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 

Is this the best way to find a country by code?

+7
dictionary list elixir nested
source share
3 answers

You can map the template as deep as you want:

 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) 

You can also use Enum.find/3 with match?/2 , which may be more readable (as suggested in another answer).

+9
source share

You can do it as follows:

 countries = [ %{name: "Deutschland", code: "DE"}, %{name: "Frankreich", code: "FR"} ] Enum.find(countries, &match?(%{code: "FR"}, &1)) # %{code: "FR", name: "Frankreich"} 
+7
source share

Elixir does not have built-in template matching for filtering individual list items based on their values.

You can write pattern matching to validate individual elements, for example:

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

And then pass this to Enum.find:

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

Or to summarize, you can:

 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"} 

Modify your search for filtering and get a list of results:

 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"}] 
+2
source share

All Articles