Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern-matching a map with string as key

Tags:

elixir

I created a map with the string "2" as one of the keys:

iex(14)> map = %{:a => 1, "2" => 2, :b => 3}
%{:a => 1, :b => 3, "2" => 2}

Now I'm not able to pattern-match it. For instance, how do I get the value associated with "2"? I tried the following but got the below error:

iex(23)> %{a: c, "2" z} = map
** (SyntaxError) iex:23: syntax error before: "2"

iex(23)> %{a: c, "2": z} = map
** (MatchError) no match of right hand side value: %{:a => 1, :b => 3, "2" => 2}
like image 461
ankush981 Avatar asked Aug 09 '16 05:08

ankush981


2 Answers

You need to use => to match string keys.

You can either use => for all keys:

iex(1)> map = %{:a => 1, "2" => 2, :b => 3}
%{:a => 1, :b => 3, "2" => 2}
iex(2)> %{:a => c, "2" => z} = map
%{:a => 1, :b => 3, "2" => 2}
iex(3)> c
1
iex(4)> z
2

or use : for atom keys (they should be after the => keys):

iex(5)> %{"2" => z, a: c} = map
%{:a => 1, :b => 3, "2" => 2}
iex(6)> z
2
iex(7)> c
1
like image 56
Dogbert Avatar answered Nov 08 '22 16:11

Dogbert


You have to remember that when your key is not an atom you can't use syntax a: value, but you have to explicitly use map syntax: "a" => value.

Also what's important you can't use atom syntax before =>, so:

 %{:a =>  a,"2" => value} = map # perfectly valid, everywhere use =>
 %{"2" => value, a: a} = map  # perfectly valid, atom syntax after regular

But this one is invalid:

 %{a: a, "2" => value} = map
 ** (SyntaxError) iex:5: syntax error before: "2"

My suggestion: when mixing atoms and strings as keys for clarity use always regular syntax.

like image 33
PatNowak Avatar answered Nov 08 '22 16:11

PatNowak