У вас есть две возможности: Kernel.match?/2
, чтобы проверить, существует ли ключ и / или Kernel.get_in/2
для глубокого извлечения значение.
iex|1 ▶ match?(%{Envelope: %{Body: %{replyMessage: _}}}, map)
#⇒ true
iex|2 ▶ get_in(map, [:Envelope, :Body, :replyMessage])
#⇒ %{
# cc: %{"amount" => "100.00", "reasonCode" => "100"},
# decision: "ACCEPT",
# invalidField: nil,
# purchaseTotals: %{"currency" => "CAD"},
# reasonCode: "100"
# }
Остерегайтесь Kernel.get_in/2
вернет nil
, если ключ существует, но имеет значение nil
, а также если ключ не существует.
Map.has_key?/2
ни в коем случае не рекурсивно, оно работает с ключами карты, переданными в качестве аргумента; при этом только первый уровень.
Примечание: можно легко построить рекурсивное решение самостоятельно на основе Map.has_key/2
defmodule Deep do
@spec has_key?(map :: map(), keys :: [atom()]) :: boolean()
def has_key?(map, _) when not is_map(map), do: false
def has_key?(map, [key]), do: Map.has_key?(map, key)
def has_key?(map, [key|tail]),
do: Map.has_key?(map, key) and has_key?(map[key], tail)
end
Deep.has_key?(map, [:Envelope, :Body, :replyMessage])
#⇒ true