Pattern matching on a map with variable as key

非 Y 不嫁゛ 提交于 2019-12-11 02:27:24

问题


How can I do pattern matching on a map which has a string key?

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"}

回答1:


If the Map is guaranteed to have only 1 entry (like you clarified in the comments), you can pass it to Map.to_list/1 and then pattern match on the result:

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"



回答2:


Here's a possible for maps with one or multiple entries using a for comprehension http://elixir-lang.github.io/getting-started/comprehensions.html

Phoenix flash messages are stored inside conn as a map with string keys, something like this:

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

This is from my layout_view.ex in the framework:

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


来源:https://stackoverflow.com/questions/39383209/pattern-matching-on-a-map-with-variable-as-key

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!