How to extract a sequence of elements from a Scala Collection

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 10.18, “How to Extract a Sequence of Elements from a Scala Collection”

Problem

You want to extract a sequence of contiguous elements from a collection, either by specifying a starting position and length, or a function.

Solution

There are quite a few collection methods you can use to extract a contiguous list of elements from a sequence, including drop, dropWhile, head, headOption, init, last, lastOption, slice, tail, take, takeWhile.

Given the following Array:

scala> val x = (1 to 10).toArray
x: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

The drop method drops the number of elements you specify from the beginning of the sequence:

scala> val y = x.drop(3)
y: Array[Int] = Array(4, 5, 6, 7, 8, 9, 10)

The dropWhile method drops elements as long as the predicate you supply returns true:

scala> val y = x.dropWhile(_ < 6)
y: List[Int] = List(6, 7, 8, 9, 10)

The dropRight method works like drop, but starts at the end of the collection and works forward, dropping elements from the end of the sequence:

scala> val y = x.dropRight(4)
y: Array[Int] = Array(1, 2, 3, 4, 5, 6)

take extracts the first N elements from the sequence:

scala> val y = x.take(3)
y: Array[Int] = Array(1, 2, 3)

takeWhile returns elements as long as the predicate you supply returns true:

scala> val y = x.takeWhile(_ < 5)
y: Array[Int] = Array(1, 2, 3, 4)

takeRight works the same way take works, but starts at the end of the sequence and moves forward, taking the specified number of elements from the end of the sequence:

scala> val y = x.takeRight(3)
y: Array[Int] = Array(8, 9, 10)

slice(from, until) returns a sequence beginning at the index from until the index until, not including until, and assuming a zero-based index:

scala> val peeps = List("John", "Mary", "Jane", "Fred")
peeps: List[String] = List(John, Mary, Jane, Fred)

scala> peeps.slice(1,3)
res0: List[String] = List(Mary, Jane)

All of these methods provide another way of filtering a collection, with their distinguishing feature being that they return a contiguous sequence of elements.

Even more methods

There are even more methods you can use. Given this list:

scala> val nums = (1 to 5).toArray
nums: Array[Int] = Array(1, 2, 3, 4, 5)

the comments after the following expressions show the values that are returned by each expression:

nums.head         // 1
nums.headOption   // Some(1)
nums.init         // Array(1, 2, 3, 4)
nums.last         // 5
nums.lastOption   // Some(5)
nums.tail         // Array(2, 3, 4, 5)

Hopefully the use of most of those methods is implied by their name. Two that might need a little explanation are init and tail. The init method returns all elements from the sequence except for the last element. The tail method returns all of the elements except the first one.

See Also

  • See the Scaladoc for any sequence (List, Array, etc.) for more methods.