如何检查 Elixir 中深度嵌套的 Map 中是否存在密钥

Ash*_*rma 4 dictionary elixir

我有一个地图对象,我需要检查它是否包含给定的键。我尝试如下,但它总是返回 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)

Ale*_*kin 8

您有两种可能性:Kernel.match?/2检查键是否存在/ Kernel.get_in/2深入检索值。

\n
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则会返回。nilnil

\n
\n

Map.has_key?/2无论如何都不是递归的,它与作为参数传递的映射的键一起使用;也就是说,仅限第一级。

\n
\n

旁注:人们可以轻松地自己构建一个递归解决方案,基于Map.has_key/2

\n
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