...

/

Unpacking Values from Lists, Maps, and Structs

Unpacking Values from Lists, Maps, and Structs

Explore pattern matching with lists, maps, and structs.

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:

%0 node_1 :a node_2 :b node_1->node_2 node_3 :c node_2->node_3 node_1629409105973 :d node_3->node_1629409105973 node_1629409084922 :e node_1629409105973->node_1629409084922 node_1629409069935 [] node_1629409084922->node_1629409069935
Elixir list 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:

iex> [a, a, "pineapples"] = ["apples", "apples", "pineapples"] 
#Output -> ["apples", "apples", "pineapples"]

The pattern [a, a, "pineapples"] means the first two list items must be the same value, and the third item must be pineapples. It demonstrates how we can use values in list patterns.

When we want to ignore some parts of a list, we can use the wildcard character (_). Type ...