So far, we have not discussed any associative data structures, i.e., data structures that can associate a certain value (or multiple values) to a key. Different languages call these features with different names like dictionaries, hashes, associative arrays, etc.
In Elixir, we have two main associative data structures: keyword lists and maps. In this chapter, we will focus on Keyword lists.
In many functional programming languages, it is common to use a list of 2-item tuples as the representation of an associative data structure. In Elixir, when we have a list of tuples and the first item of the tuple (i.e. the key) is an atom, we call it a keyword list. Consider the following example to understand the same −
list = [{:a, 1}, {:b, 2}]
Elixir supports a special syntax for defining such lists. We can place the colon at the end of each atom and get rid of the tuples entirely. For example,
list_1 = [{:a, 1}, {:b, 2}] list_2 = [a: 1, b: 2] IO.puts(list_1 == list_2)
The above program will generate the following result −
true
Both of these represent a keyword list. Since keyword lists are also lists, we can use all the operations we used on lists on them.
To retrieve the value associated with an atom in the keyword list, pass the atom as to [] after the name of the list −
list = [a: 1, b: 2] IO.puts(list[:a])
The above program generates the following result −
1
Keyword lists have three special characteristics −
In order to manipulate keyword lists, Elixir provides the Keyword module. Remember, though, keyword lists are simply lists, and as such they provide the same linear performance characteristics as lists. The longer the list, the longer it will take to find a key, to count the number of items, and so on. For this reason, keyword lists are used in Elixir mainly as options. If you need to store many items or guarantee one-key associates with a maximum one-value, you should use maps instead.
To access values associated with a given key, we use the Keyword.get function. It returns the first value associated with the given key. To get all the values, we use the Keyword.get_values function. For example −
kl = [a: 1, a: 2, b: 3] IO.puts(Keyword.get(kl, :a)) IO.puts(Keyword.get_values(kl))
The above program will generate the following result −
1 [1, 2]
To add a new value, use Keyword.put_new. If the key already exists, its value remains unchanged −
kl = [a: 1, a: 2, b: 3] kl_new = Keyword.put_new(kl, :c, 5) IO.puts(Keyword.get(kl_new, :c))
When the above program is run, it produces a new Keyword list with additional key, c and generates the following result −
5
If you want to delete all entries for a key, use Keyword.delete; to delete only the first entry for a key, use Keyword.delete_first.
kl = [a: 1, a: 2, b: 3, c: 0] kl = Keyword.delete_first(kl, :b) kl = Keyword.delete(kl, :a) IO.puts(Keyword.get(kl, :a)) IO.puts(Keyword.get(kl, :b)) IO.puts(Keyword.get(kl, :c))
This will delete the first b in the List and all the a in the list. When the above program is run, it will generate the following result −
0