Unpacking Values from Lists, Maps, and Structs
Explore pattern matching with lists, maps, and structs.
We'll cover the following...
Matching lists
Tuples represent collections of a few items. We’ve used pattern matching on them, taken values, and put them in variables. But tuples have one limitation: they’re stored contiguously in memory. We need to know in advance how many elements are inside of them. It’s a problem because we can’t always predict a collection size, and it’s impractical to write all the items of a vast collection in an expression. To address these problems, Elixir uses the list data type. In Elixir, lists are linked lists. That means each item of the collection contains a value and an implicit reference to the next element. For a list [:a, :b, :c, :d, :e]
, we’ll have something like this in memory:
A list ends by linking to an empty list, turning the list into a proper list. It’s useful to avoid infinite loops by checking if the last item is an empty list and stopping a recursive iteration. In some rare cases, we can face an improper list, one that doesn’t link to an empty list at its end.
Like with tuples, we can create pattern-matching expressions to extract values from the collection and put them into variables or check if the list items follow some pattern. For representing lists, we use the []
syntax. Let’s start our exploration by creating an expression that tells if the items are the same. Try it in the IEx below:
iex> [a, a, a] = [1, 1, 1]
#Output -> [1, 1, 1]
iex> [a, a, a] = [1, 2, 1]
#Output -> ** (MatchError) no match of right hand side value: [1, 2, 1]
iex> [a, b, a] = [1, 2, 1]
#Output -> [1, 2, 1]
iex> [a, a, a] = ["apples", "apples", "apples"]
#Output -> ["apples", "apples", "apples"]
The pattern [a, a, a]
means that a list must have three elements with the same value. We see this because we’re using the variable a
for the three items. Variables have a unique value in an expression; the variable a
can’t be the number 1
and 2
simultaneously. That’s why the list [1, 2, 1]
results in a MatchError
with [a, a, a]
but succeeds with [a, b, a]
. We can create complex checks like this one: