只是模式匹配與你所需要的關鍵:
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}
更新
你無法模式匹配變量的關鍵。問題是編譯器需要生成代碼來搜索它還不知道的東西。當你匹配模式時,你通常會給編譯器一些提示它會收到什麼。對於地圖中的鍵,提示是鍵本身。在這種情況下,即使指出第一個參數應該是查找的關鍵,但編譯器還不夠。所以你的方法應該是使用if語句:
defmodule Test2 do
def my_func(k, m) do
if Map.haskey?(k, m), do: warning(k, m), else: foo(k, m)
end
def warning(k, m) do
#Warning
m
end
# In this function you could apply the pattern matching
# described in the first part of this answer.
def foo(k, m) do
value = # do something
%{m | key => value}
end
end
我希望這能回答你的問題。
嗨,謝謝你的回答。但我應該澄清一下'my_func(key,_)'中的鍵是運行時確定的變量,在編譯時不知道 – bottlenecked
好吧,現在我已經部分地理解了你正在嘗試做什麼。你的函數究竟做了什麼? –
嗯,我不認爲它是相關的添加函數體,但最終代碼將大致做到「如果鍵已經存在觸發警告,否則做富,並將其添加到地圖」 – bottlenecked