【问题标题】:Pattern matching on a map with variable as key以变​​量为键的地图上的模式匹配
【发布时间】:2018-07-30 17:08:41
【问题描述】:

如何在具有字符串键的地图上进行模式匹配?

iex(1)> my_map = %{"key1" => "var1"}
%{"key1" => "var1"}
iex(2)> %{aa => bb} = my_map
** (CompileError) iex:2: illegal use of variable aa inside map key match, maps can only match on existing variable by using ^aa
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
iex(2)> %{"aa" => bb} = my_map
** (MatchError) no match of right hand side value: %{"key1" => "var1"}

【问题讨论】:

  • 你的意思是%{"key1" => bb} = my_map?如果您想匹配任意键,那么这是不可能的,就像第一条错误消息所说的那样。
  • @Dogbert,我想匹配一组键中的一个。
  • @Dogbert,或者可能不知道密钥的确切名称,我怎样才能得到它的名字?
  • 您的地图是否保证只包含 1 个条目?如果没有,你想要哪一个?
  • @Dogbert,保证

标签: elixir


【解决方案1】:

如果 Map 保证只有 1 个条目(就像您在 cmets 中阐明的那样),您可以将其传递给 Map.to_list/1,然后对结果进行模式匹配:

iex(1)> my_map = %{"key1" => "var1"}
%{"key1" => "var1"}
iex(2)> [{key, value}] = Map.to_list(my_map)
[{"key1", "var1"}]
iex(3)> key
"key1"
iex(4)> value
"var1"

【讨论】:

  • 如果有多个条目,例如:%{foo => %{"a" => bar}},我怎样才能将 foo 作为变量?
  • @fay 你会在 foo 之前使用 ^ 运算符。看这里:elixir-lang.org/getting-started/keywords-and-maps.html#maps
  • @fay 地图只有一个键(该键的值是地图无关紧要)。我的答案中的代码应该适合你。
【解决方案2】:

对于具有一个或多个条目的地图,可以使用 for 理解 http://elixir-lang.github.io/getting-started/comprehensions.html

Phoenix flash 消息在 conn 中存储为带有字符串键的映射,如下所示:

%{"info" => "Please check the content", "notice" => "No search results"}

这是来自我在框架中的 layout_view.ex:

defmodule MyAppWeb.LayoutView do

  use MyAppWeb, :view

  ...

  #https://hexdocs.pm/phoenix_html/Phoenix.HTML.html#sigil_E/2
  #https://hexdocs.pm/phoenix/Phoenix.Controller.html#get_flash/1

  def show_flash(conn) do
    Phoenix.Controller.get_flash(conn)
    |> flash_msg()   
  end

  def flash_msg(messages) when map_size(messages) >= 1 do    
    for { key, msg } <- messages do
      content_tag(:div, class: "mapapp-alert myapp__#{key}") do
        [ msg,
          content_tag(:span, ~E"&times;", class: "myapp-closebtn", onclick: "this.parentElement.style.display='none';")
        ]
      end
    end   
  end

  def flash_msg(_) do
    nil   
  end

end

【讨论】:

    猜你喜欢
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    相关资源
    最近更新 更多