我有一个地图对象,我需要检查它是否包含给定的键。我尝试如下,但它总是返回 false。还有如何在地图内部replyMessage上提取值,
map=%{
Envelope: %{
Body: %{
replyMessage: %{
cc: %{
"amount" => "100.00",
"reasonCode" => "100",
},
decision: "ACCEPT",
invalidField: nil,
purchaseTotals: %{"currency" => "CAD"},
reasonCode: "100",
}
}
}
}
Map.has_key?(map, %{Envelope: %{Body: %{replyMessage: replyMessage}}})= false
Run Code Online (Sandbox Code Playgroud)
您有两种可能性:Kernel.match?/2
检查键是否存在和/或 Kernel.get_in/2
深入检索值。
iex|1 \xe2\x96\xb6 match?(%{Envelope: %{Body: %{replyMessage: _}}}, map) \n#\xe2\x87\x92\xc2\xa0true\n\niex|2 \xe2\x96\xb6 get_in(map, [:Envelope, :Body, :replyMessage])\n#\xe2\x87\x92\xc2\xa0%{\n# cc: %{"amount" => "100.00", "reasonCode" => "100"},\n# decision: "ACCEPT",\n# invalidField: nil,\n# purchaseTotals: %{"currency" => "CAD"},\n# reasonCode: "100"\n# }\n
Run Code Online (Sandbox Code Playgroud)\n请注意,如果键存在但具有值,或者键不存在,Kernel.get_in/2
则会返回。nil
nil
Map.has_key?/2
无论如何都不是递归的,它与作为参数传递的映射的键一起使用;也就是说,仅限第一级。
旁注:人们可以轻松地自己构建一个递归解决方案,基于Map.has_key/2
defmodule Deep do\n @spec has_key?(map :: map(), keys :: [atom()]) :: boolean()\n def has_key?(map, _) when not is_map(map), do: false\n def has_key?(map, [key]), do: Map.has_key?(map, key)\n def has_key?(map, [key|tail]),\n do: Map.has_key?(map, key) and has_key?(map[key], tail)\nend\n\nDeep.has_key?(map, [:Envelope, :Body, :replyMessage])\n#\xe2\x87\x92\xc2\xa0true\n
Run Code Online (Sandbox Code Playgroud)\n