🎓 A1Learner
🔍
0 of 48 lessons completed

Scala Matching Collections

Matching a collection is a match that tests the shape of a list, not just one value. List patterns name the first items and the rest of the list.

A list pattern splits head and tail

The pattern binds the first item and the rest of the list. The tail length counts the remaining items.

@main def main(): Unit =
  val result = List(10, 20, 30) match
    case head :: tail => head + ":" + tail.length
    case Nil => "empty"
  println(result)

Nil matches an empty list

An empty list has no head to bind. The Nil case runs instead.

@main def main(): Unit =
  val xs: List[Int] = List()
  val result = xs match
    case Nil => "empty"
    case _ => "not empty"
  println(result)

A fixed pattern matches exactly two items

Two names plus Nil need a list of exactly two items. This list has exactly two, so the case adds them.

@main def main(): Unit =
  val result = List(4, 9) match
    case a :: b :: Nil => a + b
    case _ => 0
  println(result)

Example

def describe(xs: List[Int]): String = xs match
  case Nil => "empty"
  case x :: Nil => "one: " + x
  case x :: y :: rest => "many: " + (x + y) + " rest " + rest.length
@main def main(): Unit =
  println(describe(List(1, 2, 3, 4)))
  println(describe(List()))

Key points

  • List pattern: a pattern such as head :: tail that splits a list into its head and its tail.
  • Use Nil to match an empty list.
  • Use a pattern such as a :: b :: Nil to match a list of exactly two items.
  • A pattern with head :: tail matches any non-empty list.
  • The bound tail is itself a list, so its length counts the remaining items.

In this example, describe tries three list shapes in order. A four-item list takes the many case, and an empty list takes the Nil case. The two lines prove both shapes work.

Note

a list pattern matches by shape, so a list of the wrong length falls through to the next case.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

What does List(5, 6, 7) match with case h :: t => t.length and case Nil => 0 give?