Elixir Maps

Welcome to a tutorial on Elixir. Here you will learn about Maps in Elixir.

In Elixir, Keyword lists are a convenient way to address content stored in lists by key. However, Elixir is still walking through the list underneath it. This could be good if there are other plans for the list which require working through all of it but can be unnecessary overhead if you plan to use keys as your only approach to the data instead.

With the above scenario, maps come in. This is because maps are the 'go-to' data structure whenever there is a need for a key-value store in Elixir.

 

Creating a Map

We create a map by using the %{} syntax, as shown below.

map = %{:a => 1, 2 => :b}

 

If compared to the keyword lists, two differences exist, which are:

  • A Map allows any value as a key.
  • A Map's keys do not follow any order.

 

Accessing a key

Now, to access any value associated with a key, Maps use the same syntax as Keyword lists. 

map = %{:a => 1, 2 => :b}
IO.puts(map[:a])
IO.puts(map[2])

Now, if the above code is run, the output will be:

1
b

 

Inserting a key

Here, to insert a key in a map, the Dict.put_new function is used as it takes the map, new key, and new value as arguments

map = %{:a => 1, 2 => :b}
new_map = Dict.put_new(map, :new_val, "value") 
IO.puts(new_map[:new_val])

The above code will insert the key-value pair :new_val - "value" in a new map. When the above code is run, the output is:

"value"

 

Updating a Value

In order to update a value already present in the map, the syntax below can be used.

map = %{:a => 1, 2 => :b}
new_map = %{ map | a: 25}
IO.puts(new_map[:a])

The output is:

25

 

Pattern Matching

Unlike keyword lists, maps are useful with pattern matching. This is because if a map is used in a pattern, it always matches a subset of the given value, as shown below.

%{:a => a} = %{:a => 1, 2 => :b}
IO.puts(a)

The output is: 

1

In the above, a is matched a with 1. Therefore, it generates output 1.

Also, just as shown above, a map matches as long as the keys in the pattern exist in the given map. Thus, an empty map matches all maps.

In addition, variables can be used when accessing, matching, and adding map keys. This is shown below:

n = 1
map = %{n => :one}
%{^n => :one} = %{1 => :one, 2 => :two, 3 => :three}

In Elixir, the Map module provides a similar API to the Keyword module with convenience functions to manipulate maps. The Map.get, Map.delete function can be used to manipulate maps.

 

Maps with Atom keys

Maps come with a few interesting properties, such that if all the keys in a map are atoms, the keyword syntax below can be used for convenience:

map = %{:a => 1, 2 => :b} 
IO.puts(map.a) 

Also, another interesting property of maps is that they provide their own syntax for updating and accessing atom keys.

map = %{:a => 1, 2 => :b}
IO.puts(map.a)

The output is:

1

 

NOTE: access atom keys in this that to access atom keys in this way, should exist or the program will fail to work.