Pattern Matching a Function Body: Lists

Pattern matching a list with function clauses is the foundation of recursively processing a list of data. We aren’t going to go into recursion here, but instead focus on getting comfortable with the different ways we can Pattern Match a list with function clauses.

Practice Exercises

The following exercises continue using the Pattern Matching project. We will continue focusing on making a single test pass at a time.

The tests we are focusing on are in test/lists_test.exs. Running the following command will execute all the tests in this file. Running all the tests now will show they all fail.

$ mix test test/lists_test.exs

[...]

Finished in 0.1 seconds
7 tests, 7 failures

Randomized with seed 423605

Exercise #1 – Lists.is_empty?/1

In Elixir, a function can have the question mark character ? as part of the name. By convention, this is used to convey that it returns a boolean result. This function works this way as well. If given an empty list, true is returned. For anything else it returns false.

mix test test/lists_test.exs:25

Exercise #2 – Lists.has_1_item?/1

This function also returns a boolean result because of the ? in the name. If given a list with exactly 1 item, return true. For anything else it returns false.

mix test test/lists_test.exs:35

Exercise #3 – Lists.at_least_one?/1

This function also returns a boolean result because of the ? in the name. If the list is not empty, return true. For anything else it returns false.

mix test test/lists_test.exs:40

Exercise #4 – Lists.return_first_item/1

If the list is not empty, return the first item. If the list is empty, return the atom :error.

mix test test/lists_test.exs:50

Exercise #5 – Lists.starts_with_1?/1

If the list starts with a value of 1, then return true. Any other initial value returns false.

mix test test/lists_test.exs:60

Exercise #6 – Lists.sum_pair/1

If the list has exactly two items, add them together and return the result. If the list doesn’t have exactly two items, return the atom :error.

mix test test/lists_test.exs:70

Exercise #7 – Lists.sum_first_2/1

Given a non-empty list, take the first two elements from it, sum them together and make the summed value be the new head of the list. If the list doesn’t have at least two items in it, return the original passed in value.

mix test test/lists_test.exs:80

Comments are closed

This is a static version of the site. Comments are not available.

8 Comments

  1. romenigld on December 14, 2020 at 10:58 am

    I like the exercises.
    I just notice the exact number for run the tests.
    They aren’t running in the beginning of each tests.
    Exercise #1: mix test test/lists_test.exs:22
    Exercise #2: mix test test/lists_test.exs:32
    and the so on….

    • Mark Ericksen on March 13, 2021 at 6:43 pm

      Right! You just pick a line that’s inside the test. I like to pick something around the middle so if I add or delete lines, the correct test is still run.

  2. Uzo Enudi on March 13, 2021 at 11:24 am

    Solution:
    def sum_pair([first, second]), do: first + second

    My solution:
    def sum_pair([first, second | []]), do: first + second

    Some overthinking went in there 🙂

    • Mark Ericksen on March 13, 2021 at 6:43 pm

      But hey! It works! 🙂

  3. Maksym Kosenko on December 8, 2021 at 12:25 pm

    For exercise 1 this only one function covers all tests:

    def is_empty?(something), do: something == []
    

    I don’t know if it fits the philosophy of Elixir

    • Mark Ericksen on December 8, 2021 at 12:38 pm

      Ha! Yes, that works. This is more about practicing applying pattern matching in function headers. In case it wasn’t already known, you could use Enum.empty?(something) instead of writing a custom function at all! So, it’s really just about practice. 🙂

  4. Marcus West on August 15, 2024 at 4:31 pm

    def sum_first_2([first, second | tl]), do: [first + second | tl]
    IO.inspect(PatternMatching.Lists.sum_first_2([41,5,119,118]))
    —> ~c”.wv”

    For some reason, it just won’t behave on this. And here is my setup

    pattern_matching/lib/pattern_matching on 🐢 main [!?] ❄️ 🌴🌴 elixir -v
    Erlang/OTP 27 [erts-15.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]

    Elixir 1.17.1 (compiled with Erlang/OTP 27)

    • L0cutus on December 8, 2024 at 2:43 am


      def sum_first_2([first, second | tl]), do: [first + second | tl]
      IO.inspect(PatternMatching.Lists.sum_first_2([41,5,119,118]))
      —> ~c”.wv”
      For some reason, it just won’t behave on this. And here is my setup

      try:
      IO.inspect(PatternMatching.Lists.sum_first_2([41,5,119,118]), charlists: :as_lists)

Comments are closed on this static version of the site.