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?