The many different ways to key Elixir Maps

Essential Elixir : part 9 of 10 published on May 20, 2016

Using an Atom as a key

This obviously works. Nothing unexpected here.

> map = %{ name: "JB" }
> %{ name: name } = map
> name
"JB"

But what you might not know is that "key": also uses an atom as the key. So yes, you obviously can do this:

> map = %{ "name": "JB" }
> %{ "name": name } = map
> name
"JB"

But that also means you can do:

> map = %{ name: "JB" }
> %{ "name": name } = map
> name
"JB"

Or:

> map = %{ "name": "JB" }
> %{ name: name } = map
> name
"JB"

But what you CAN’T do is:

> map = %{ "name": "JB" }
> %{ "name" => name } = map
** (MatchError) no match of right hand side value: %{name: "JB"}

It doesn’t match because name: and "name": are Atoms and "name" => is a String.

Using a String as a key

So naturally, the reverse is true. If you use a String when you set the key on the Map, you can’t match against Atom’s as keys.

> map = %{ "name" => "JB" }
> %{ "name" => name } = map
> name
"JB"

And if you try using an Atom, you get a MatchError.

> map = %{ "name" => "JB" } 
> %{ name: name } = map
** (MatchError) no match of right hand side value: %{"name" => "JB"}

This is the GOTCHA one.

> map = %{ "name" => "JB" } 
> %{ "name": name } = map
** (MatchError) no match of right hand side value: %{"name" => "JB"}

Using anything else as a key

Given that the above is true, it is easy to deduce and verify that you can use a whole mess of things as keys in an Elixir Map.

Integers? Sure.

> map = %{ 3 => "JB" }
> %{ 3 => name } = map
> name
"JB"

Tuples? Sure.

> map = %{ {"hi"} => "foo" }
> %{ {"hi"} => name } = map 
> name
"JB"

Lists? Sure.

> map = %{ [1,"hi"] => "JB" }
%{[1, "hi"] => "JB"}
> %{ [1, "hi"] =>  name } = map
> name
"JB"

How about other Maps? Shine on you crazy diamond.

> other_map = %{message: "hi" }
%{message: "hi"}
> map = %{ other_map: "JB" }
%{other_map: "JB"}
> %{ other_map: name } = map
%{other_map: "JB"}
> name
"JB"

Conclusion

This is one of those things that seems obvious after you run into it, but hopefully with this knowledge you can shorten any future WTF moments. Always more to learn about Maps. :)

Next: Piping to an anonymous function