【发布时间】:2019-12-02 00:41:20
【问题描述】:
我有一个所需密钥列表(required_keys):
["artist", "track", "year"]
和地图(参数):
%{"track" => "bogus", "artist" => "someone"}
我想确定params 是否有required_keys。我来自 Ruby 背景,对于 Elixir 来说迭代似乎是错误的,但不确定如何进行模式匹配。
【问题讨论】:
标签: elixir
我有一个所需密钥列表(required_keys):
["artist", "track", "year"]
和地图(参数):
%{"track" => "bogus", "artist" => "someone"}
我想确定params 是否有required_keys。我来自 Ruby 背景,对于 Elixir 来说迭代似乎是错误的,但不确定如何进行模式匹配。
【问题讨论】:
标签: elixir
使用Enum.all?/2 和Map.has_key?/2:
iex(1)> map = %{"track" => "bogus", "artist" => "someone"}
%{"artist" => "someone", "track" => "bogus"}
iex(2)> map2 = %{"track" => "bogus", "artist" => "someone", "year" => 2016}
%{"artist" => "someone", "track" => "bogus", "year" => 2016}
iex(3)> required_keys = ["artist", "track", "year"]
["artist", "track", "year"]
iex(4)> Enum.all?(required_keys, &Map.has_key?(map, &1))
false
iex(5)> Enum.all?(required_keys, &Map.has_key?(map2, &1))
true
但不确定如何进行模式匹配
如果required_keys 是动态的,则无法进行模式匹配。如果是静态列表,可以使用模式匹配:
iex(6)> match?(%{"artist" => _, "track" => _, "year" => _}, map)
false
iex(7)> match?(%{"artist" => _, "track" => _, "year" => _}, map2)
true
【讨论】:
requireds = ["artist", "track", "year"]
params = %{"track" => "bogus", "artist" => "someone"}
Enum.all?( requireds, fn(k) -> Map.has_key?(params, k) end) # => false
requireds = ["artist", "track"]
Enum.all?( requireds, fn(k) -> Map.has_key?(params, k) end) # => true
或使用模式匹配:
def has_required_params?(%{"artist" => _, "track" => _, "year" => _}), do: true
def has_required_params?(_), do: false
has_required_params?(%{"track" => "bogus", "artist" => "someone"}) # => false
has_required_params?(%{"track" => "bogus", "artist" => "someone", year => "2000"}) # => true
【讨论】:
使用in 代替Map.has_key?:
def contains_fields?(keys, fields), do: Enum.all?(fields, &(&1 in keys))
【讨论】: