您可以根据具体问题和您使用的 Elixir 版本尝试多种方法:
- 地图模式匹配
- 检查给定键是否存在 (Elixir
- 检查给定键是否存在 (Elixir >= 1.10)
地图模式匹配
如果你可以用你需要的键进行模式匹配:
defmodule Test do
def my_func(%{"a" => value}), do: {:a, value}
def my_func(%{"b" => value}), do: {:b, value}
def my_func(_), do: :error
end
然后在IEx中:
iex(1)> Test.my_func(%{"a" => 1})
{:a, 1}
iex(2)> Test.my_func(%{"b" => 2})
{:b, 2}
子句的顺序也很重要,例如如果您尝试匹配 %{"b" => 2} 但您有以下映射 %{"a" => 1, "b" => 2},则键 "a" 将首先匹配,因为在第一个子句中:
iex(3)> Test.my_func(%{"a" => 1, "b" => 2})
{:a, 1}
如果您想为每个可以匹配的键生成一些东西,我推荐一种不同的方法。例如,如果您想将函数映射到这些键:
defmodule Test0 do
def my_op({"times_2", value}), do: {"times_2", value * 2}
def my_op({"times_3", value}), do: {"times_3", value * 3}
def my_op({key, value}), do: {key, value}
def my_func(m) do
Enum.map(m, &my_op/1) |> Enum.into(%{})
end
end
所以你会得到以下结果:
iex(1)> Test0.my_func(%{"times_2" => 2, "times_3" => 3, "whatever" => 42})
%{"times_2" => 4, "times_3" => 9, "whatever" => 42}
检查给定键是否存在(Elixir
您无法将键与变量进行模式匹配。问题是编译器需要生成代码来搜索它还不知道的东西。当你进行模式匹配时,你通常会给编译器一些关于它将接收什么的提示。对于地图中的键,提示是键本身。在这种情况下,即使指出第一个参数应该是要查找的关键,对于编译器来说也是不够的。所以你的方法应该是使用 if 语句:
defmodule Test1 do
def my_func(k, m) do
if Map.has_key?(k, m) do
... do something when key is found ...
else
... do something when key is not found ...
end
end
end
检查给定密钥是否存在 (Elixir >= 1.10)
Elixir 1.10 终于添加了可以用来解决这个问题的守卫is_map_key/2!
defmodule Test2 do
def my_func(key, map) when is_map_key(map, key) do
... key is found ...
end
def my_func(_, _) do
... key is not found ...
end
end
这肯定会解决编译问题:)
我希望这能回答你的问题。