Filtering/Pattern 匹配嵌套数据结构

Filtering/Pattern Matching in nested data structure

我是 Elixir 的新手,对模式匹配仍然很困惑。

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

这是通过代码查找国家/地区的最佳方式吗?

您可以根据需要进行模式匹配:

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)

您还可以将 Enum.find/3match?/2 一起使用,这可能更具可读性(如另一个答案中所建议)。

你可以这样做:

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

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

Elixir 没有内置模式匹配来尝试根据它们的值过滤掉列表中的某些项目。

您可以编写模式匹配来检查单个项目,如下所示:

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