« Back to blog

Erlang Dictionary Example

Chances are your looking for examples on how to use a Dictionary in Erlang. In this tutorial we will cover the “dict” module, which is one of the more common dictionary data structures found in the Erlang programming language. We will attempt to illustrate the various ways to manipulate a dictionary through the “dict” module. Erlang bundles with various dictionary based modules but in this tutorial we will focus on the “dict” module exclusively.

The dict module is a fairly complete implementation of a key-value dictionary. Through the dict module you can expect to find functions for adding, appending, removing, and updating key-value pairs in a dictionary. Functions for getting the size of the dictionary and checking for the existence of keys are also provided. The dict module also contains functional operations like fold, filter and map. Let’s jump right into the dict module and explore the functions available.

First lets explore how to create a dictionary and store key-value pairs in the dictionary with the new function and store function. Here we will create a dictionary and add the key: color and the value: blue to the dictionary.

Note, we don’t display the output from functions that create dictionaries in order to keep the examples noise free.  However, we will display any output that illustrates the purpose of a function we are exploring.

1> D = dict:new().
2> D1 = dict:store(color, blue, D).

At this point, we have created a new dictionary D and proceeded by storing the key-value color:blue in the dictionary. Notice that most functions in the dict module require a dictionary as an argument and return a new dictionary. If your coming from an imperative language like Java you might be wondering why this is the case. Since Erlang is a functional language it focuses on the concept of not storing state, so each time you mutate a dictionary by adding or removing elements, the dict module simply returns a new instance of the dictionary. This makes the dictionary process-safe and allows for consistent concurrency.

Now lets enhance our example by adding a key-value pair were the value is a list of items. Once we have a key that maps to a list of elements, we will append new values to the list. We will use the append function for adding multiple values to a given key.

3> D2 = dict:store(colors, [black], D1).
4> D3 = dict:append(colors, white, D2).

Our example dictionary now contains the following pairs: color:blue, colors:[black,white]. Now we are at a good point to illustrate how to fetch values from the dictionary that is associated with a given key. Lets demonstrate how to fetch the values from the key “colors”. Also, be aware that if the key specified in the fetch function is not present in the dictionary, an exception will be raised.

5> io:fwrite("values for key: colors: ~p~n", [dict:fetch(colors, D3)]).
values for key: colors: [black,white]

As you can see our dictionary contains the expected values: black and white for the given key: colors. Lets go a small tangent and demonstrate how to get the size of the dictionary before we continue to illustrate how to add and remove pairs.

6> io:fwrite("dictionary size: ~p~n", [dict:size(D3)]). 
dictionary size: 2
ok

The size function effectively displays the size of the dictionary. Lets go back to adding values to the dictionary. A useful function of the dict module is the append_list function. This function lets you add a list of elements as the value of a specified key. For example, we defined the key colors and added the values black and white, now lets append the values green and orange. Once we append the values we will follow with a fetch operation on the dictionary for the key colors to show verify that our new values were successfully appended to the dictionary.

7> D4 = dict:append_list(colors, [green, orange], D3). 
8> io:fwrite("values for key: colors: ~p~n", [dict:fetch(colors, D4)]). 
values for key: colors: [black,white,green,orange]
ok

Wow that couldn’t be any easier? Okay we are half way through the dict module, stay with me and lets blow this module out of the water.

Now lets move on to removing elements from the dictionary. The dict module contains the erase function for deleting all elements from the dictionary that match the specified key. For this example, we will add a new key-value pair to our dictionary, fetch the value associated with the new key, display the size of the dictionary, delete the newly added key-value pair and lastly display the size of the dictionary.

9> D5 = dict:store(shape, square, D4).
10> io:fwrite("value for key shape: ~p~n", [dict:fetch(shape, D5)]).
value for key shape: square
ok        
11> io:fwrite("dictionary size: ~p~n", [dict:size(D5)]).
dictionary size: 3
ok
D6 = dict:erase(shape, D5).
12> io:fwrite("dictionary size: ~p~n", [dict:size(D6)]).
dictionary size: 2
ok

As expected, we can see in this example how we were able to store a new key-value pair, then fetch it, and see our dictionary grew in size by one. After deleting the newly added key-value pair with the erase function, our dictionary decreased in size by one.

Just for completeness, lets cover the find function. The find function is similar to fetch, it gets the value associated with a given key. If the key provided is not available in the dictionary, an error is returned. The return value of the find function is a tuple {ok, Value} or error, if the given key is not in the dictionary.

13> io:fwrite("value for key color: ~p~n", [dict:find(color, D6)]).
value for key color: {ok,blue}
ok
14> io:fwrite("value for key color: ~p~n", [dict:find(square, D6)]).
value for key color: error
ok

Here we can see how the find function was able to find the value of the specified key in our dictionary. And when we tried to find a key that did not exist in the dictionary we received an error as the return value. Basically, the difference between fetch and find is that find is less intrusive, in the sense that it will not raise an exception when the specified key is not in the dictionary whereas fetch will.

Next, lets explore how to list all the keys contained in our dictionary. The dict module contains the fetch_keys function that does exactly that. The fetch keys function returns a list with all the keys in the dictionary.

15> io:fwrite("store keys: ~p~n", [dict:fetch_keys(D6)]).
store keys: [color,colors]
ok

Now we go full circle and back to creating dictionaries. The dict module contains a useful function for creating dictionaries from a given list of tuples. The tuples in the list take the form of {Key, Value}. Lets jump right into the from_list function and see it in action.

16> D7 = dict:from_list([{people, abel}, {people, anthony}, {animals, tiger}]).

In this example we killed two birds with one stone. We construct a new dictionary from the list of tuples. Notice in the list of tuples, we defined two tuples with the same key: people. The end result is that our newly constructed dictionary will contain two keys i.e., people and animals. With the key people containing two values: abel and anthony. In other words the from_list function is smart enough to detect multiple values for the key people, cool isn’t it?

And there you have it, we covered most of the functions available in the dict module (new, store, append, append_list, fetch, find, size, from_list, erase, and fetch_keys) with the exception of fold, filter and map. In the second part of this tutorial we will cover these functions.

| Viewed
times
Filed under: