lapinkoira
lapinkoira

Reputation: 8978

Pattern matching Enum.map vs case condition

I have this map:

%{
  "a" => "1",
  "b" => "2",
  "c" => "3",
  "d" => "4",
  "e" => %{"f" => "5"}
}

And I can iterate its key value like this:

Enum.map(map, fn({k, v}) ->  
  v
end)

Using fn({k, v}) like a tuple and I obtain something like this:

["1", "2", "3", "4", %{"f" => "5"}]

But I dont understand why this doesnt work:

Enum.map(map, fn({k, v}) ->  
  case v do
    {key, value} -> "inner map"
    _ -> "something else"
end)
["something else", "something else", "something else", "something else",
 "something else"]

I can pattern match the map with fn({k, v}) but I cant use the same pattern match for the case condition?

Update

That's what I am trying

some = %{"a" => "1", "b" => "2", "c" => "3", "d" => "4", "e" => %{"f" => "5"}}
Enum.map(some, fn({k, v}) ->       
  case v do                        
    %{^condition => value} -> "inner map"
    _ "something else"
  end
end)
** (CompileError) iex:15: unknown variable ^condition. No variable "condition" has been defined before the current pattern
    (stdlib) lists.erl:1354: :lists.mapfoldl/3

Upvotes: 0

Views: 2461

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 120990

{key, value} is not a map, it’s a tuple. You need:

Enum.map(map, fn({k, v}) ->  
  case v do
    %{} = map -> "inner map: #{inspect map}"
    _ -> "something else"
  end
end)
#⇒ ["something else", "something else",
#   "something else", "something else",
#   "inner map: %{\"f\" => \"5\"}"]

Whether the existence of a key is proven, one might pattern match it’s value directly (note pinned key):

key = "f"
Enum.map(map, fn({k, v}) ->  
  case v do
    %{^key => v} -> "inner map with value: #{inspect v}"
    _ -> "something else"
  end
end)
#⇒ ["something else", "something else",
#   "something else", "something else",
#⇒  "inner map with value: \"5\""]

Upvotes: 4

Related Questions