> For the complete documentation index, see [llms.txt](https://practical-elixir.woojiahao.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://practical-elixir.woojiahao.com/elixir-fundamentals/pattern-matching.md).

# Pattern matching

The `=` operator is known as the match operator in Elixir. This is because the implicit behavior of `=` is to perform a match between the left hand side and right hand side of the equation. This is on top of the existing assignment behavior. As a result, the following code can be interpreted as:

```elixir
iex(1)> x = 1 # This is assigning the value 1 to variable x
1
iex(2)> 1 = x # This is matching the value of variable x to 1 (checks if LHS == RHS)
1
iex(3)> 2 = x # This fails because variable x holds value of 1, so the match fails
** (MatchError) no match of right hand side value: 1
    (stdlib 5.2) erl_eval.erl:498: :erl_eval.expr/6
    iex:3: (file)
```

As a result, `=` can be used to de-structure a variable into its "parts" as it will map all matched LHS values to the found values on the RHS. This is also known as **pattern matching**.

## Tuples

For instance, you can de-structure the contents of a tuple:

```elixir
iex(3)> x = {:a, "hello", 1}
{:a, "hello", 1}
iex(4)> {atom_var, str_var, num_var} = x
{:a, "hello", 1}
iex(5)> atom_var
:a
iex(6)> str_var
"hello"
iex(7)> num_var
1
```

Notice how each value of the tuple `x` is directly matched to a variable on the LHS. Additionally, if you attempt to de-structure/pattern match a variable with mismatched "parts", you will receive an error:

```elixir
iex(8)> {atom_var, str_var, num_var, failed_var} = x
** (MatchError) no match of right hand side value: {:a, "hello", 1}
    (stdlib 5.2) erl_eval.erl:498: :erl_eval.expr/6
    iex:8: (file)
```

## Lists

You can also perform pattern matching on lists. However, since lists are of variable length (compared to tuples), you may not know the exact number of elements in a list when pattern matching, so you can use the `|` operator instead:

```elixir
iex(8)> l = [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
iex(9)> [h | t] = l
[1, 2, 3, 4, 5, 6]
iex(10)> h
1
iex(11)> t
[2, 3, 4, 5, 6]
```

The `|` operator works like the `hd/1` and `tl/1` function in one.

You can optionally "ignore" a variable in pattern matching by replacing it with `_` so the part will still be matched but not assigned to any variable or compared against anything:

```elixir
iex(12)> [a | _] = l
[1, 2, 3, 4, 5, 6]
iex(13)> a
1
```

## Maps

As mentioned in [Keyword lists and maps](/elixir-fundamentals/types/keyword-lists-and-maps.md), while keyword lists support pattern matching, their order dependent nature makes it hard to use with pattern matching. However, maps are the perfect candidate for pattern matching against "dynamic" structures:

```elixir
iex(15)> %{:a => a, "hello" => world_var, 2 => _} = d
%{2 => :b, :a => 1, "hello" => "world"}
iex(16)> a
1
iex(17)> world_var
"world"
```

## Deeply nested structures

Pattern matching also applies to any nested structures as long as you know its "parts" ahead of time:

```elixir
iex(18)> n = [:a, %{"hello" => "world", :b => %{"nested" => "value"}}]
[:a, %{:b => %{"nested" => "value"}, "hello" => "world"}]
iex(19)> [_, %{:b => %{"nested" => nested_var}}] = n
[:a, %{:b => %{"nested" => "value"}, "hello" => "world"}]
iex(20)> nested_var
"value"
```
