How to choose a Scala collection method to solve a problem

Note: This is an excerpt from the Scala Cookbook (partially re-worded and re-formatted for the internet). This is Recipe 10.3, “How to choose a Scala collection method to solve a problem.”

Problem

There are a large number of methods available to Scala collections, and you need to choose a method to solve a problem.

Solution

The Scala collection classes provide a wealth of methods that can be used to manipulate data. Most methods take either a function or a predicate as an argument. (A predicate is just a function that returns a Boolean.)

The methods that are available are listed in two ways in this recipe. In the next few paragraphs, the methods are grouped into categories to help you easily find what you need. In the tables that follow, a brief description and signature of each method is provided.

Methods organized by category

Filtering methods

Methods that can be used to filter a collection include collect, diff, distinct, drop, dropWhile, filter, filterNot, find, foldLeft, foldRight, head, lastOption, init, intersect, last, lastOption, reduceLeft, reduceRight, remove, slice, tail, take, takeWhile, and union.

Transformer methods

Transformer methods take at least one input collection to create a new output collection, typically using an algorithm you provide. They include +, ++, −, −−, diff, distinct, collect, flatMap, map, reverse, sortWith, takeWhile, zip, and zipWithIndex.

Grouping methods

These methods let you take an existing collection and create multiple groups from the input collection. These methods include groupBy, partition, sliding, span, splitAt, and unzip.

Informational and mathematical methods

These methods provide information about a collection, and include canEqual, contains, containsSlice, count, endsWith, exists, find, forAll, hasDefiniteSize, indexOf, indexOfSlice, indexWhere, isDefinedAt, isEmpty, lastIndexOf, lastIndexOfSlice, lastIndexWhere, max, min, nonEmpty, product, segmentLength, size, startsWith, sum. The methods foldLeft, foldRight, reduceLeft, and reduceRight can also be used with a function you supply to derive information about a collection.

Others

A few other methods are hard to categorize, including par, view, flatten, foreach, and mkString:

  • par creates a parallel collection from an existing collection
  • view creates a lazy view on a collection (see Recipe 10.24)
  • flatten converts a list of lists down to one list
  • foreach is like a for loop, letting you iterate over the elements in a collection
  • mkString lets you build a String from a collection

There are even more methods than those listed here. For instance, there’s a collection of to* methods (toArray, toBuffer, etc.) that let you convert the current collection (a List, for example) to other collection types (Array, Buffer, Vector, etc.). Check the Scaladoc for your collection class to find more built-in methods.

Common collection methods

The following tables list the most common collection methods.

Table 10-8 lists methods that are common to all collections via Traversable. The following symbols are used in the first column of the table:

  • c refers to a collection
  • f refers to a function
  • p refers to a predicate
  • n refers to a number
  • op refers to a simple operation (usually a simple function)

Additional methods for mutable and immutable collections are listed in Table 10-9 and Table 10-10, respectively.

Table 10-8. Common methods on Traversable collections

Method Description
c collect f Builds a new collection by applying a partial function to all elements of the collection on which the function is defined.
c count p Counts the number of elements in the collection for which the predicate is satisfied.
c1 diff c2 Returns the difference of the elements in c1 and c2.
c drop n Returns all elements in the collection except the first n elements.
c dropWhile p Returns a collection that contains the “longest prefix of elements that satisfy the predicate.”
c exists p Returns true if the predicate is true for any element in the collection.
c filter p Returns all elements from the collection for which the predicate is true.
c filterNot p Returns all elements from the collection for which the predicate is false.
c find p Returns the first element that matches the predicate as Some[A]. Returns None if no match is found.
c flatten Converts a collection of collections (such as a list of lists) to a single collection (single list).
c flatMap f Returns a new collection by applying a function to all elements of the collection c (like map), and then flattening the elements of the resulting collections.
c foldLeft(z)(op) Applies the operation to successive elements, going from left to right, using the initial seed value z.
c foldRight(z)(op) Applies the operation to successive elements, going from right to left, using the initial seed value z.
c forAll p Returns true if the predicate is true for all elements, false otherwise.
c foreach f Applies the function f to all elements of the collection.
c groupBy f Partitions the collection into a Map of collections according to the function.
c hasDefiniteSize Tests whether the collection has a finite size. (Returns false for a Stream or Iterator, for example.)
c head Returns the first element of the collection. Throws a NoSuchElementException if the collection is empty.
c headOption Returns the first element of the collection as Some[A] if the element exists, or None if the collection is empty.
c init Selects all elements from the collection except the last one. Throws an UnsupportedOperationException if the collection is empty.
c1 intersect c2 On collections that support it, it returns the intersection of the two collections (the elements common to both collections).
c isEmpty Returns true if the collection is empty, false otherwise.
c last Returns the last element from the collection. Throws a NoSuchElementException if the collection is empty.
c lastOption Returns the last element of the collection as Some[A] if the element exists, or None if the collection is empty.
c map f Creates a new collection by applying the function to all the elements of the collection.
c max Returns the largest element from the collection.
c min Returns the smallest element from the collection.
c nonEmpty Returns true if the collection is not empty.
c par Returns a parallel implementation of the collection, e.g., Array returns ParArray.
c partition p Returns two collections according to the predicate algorithm.
c product Returns the multiple of all elements in the collection.
c reduceLeft op The same as foldLeft, but begins at the first element of the collection.
c reduceRight op The same as foldRight, but begins at the last element of the collection.
c reverse Returns a collection with the elements in reverse order. (Not available on Traversable, but common to most collections, from GenSeqLike.)
c size Returns the size of the collection.
c slice(from, to) Returns the interval of elements beginning at element from and ending at element to.
c sortWith f Returns a version of the collection sorted by the comparison function f.
c span p Returns a collection of two collections; the first created by c.takeWhile(p), and the second created by c.dropWhile(p).
c splitAt n Returns a collection of two collections by splitting the collection c at element n.
c sum Returns the sum of all elements in the collection.
c tail Returns all elements from the collection except the first element.
c take n Returns the first n elements of the collection.
c takeWhile p Returns elements from the collection while the predicate is true. Stops when the predicate becomes false.
c1 union c2 Returns the union (all elements) of two collections.
c unzip The opposite of zip, breaks a collection into two collections by dividing each element into two pieces, as in breaking up a collection of Tuple2 elements.
c view Returns a nonstrict (lazy) view of the collection.
c1 zip c2 Creates a collection of pairs by matching the element 0 of c1 with element 0 of c2, element 1 of c1 with element 1 of c2, etc.
c zipWithIndex “Zips” the collection with its indices.

Mutable collection methods

Table 10-9 shows the common methods for mutable collections. (Although these are all methods, they’re occasionally referred to as “operators,” because that’s what they look like.)

Table 10-9. Common operators (methods) on mutable collections

Operator (method) Description
c += x Adds the element x to the collection c.
c += (x,y,z) Adds the elements x, y, and z to the collection c.
c1 ++= c2 Adds the elements in the collection c2 to the collection c1.
c −= x Removes the element x from the collection c.
c −= (x,y,z) Removes the elements x , y, and z from the collection c.
c1 −−= c2 Removes the elements in the collection c2 from the collection c1.
c(n) = x Assigns the value x to the element c(n).
c clear Removes all elements from the collection.
c remove n
c.remove(n, len)
Removes the element at position n, or the elements beginning at position n and continuing for length len.

There are additional methods, but these are the most common. See the Scaladoc for the mutable collection you’re working with for more methods.

Immutable collection operators

Table 10-10 shows the common methods for working with immutable collections. Note that immutable collections can’t be modified, so the result of each expression in the first column must be assigned to a new variable. (Also, see Recipe 10.6 for details on using a mutable variable with an immutable collection.)

Table 10-10. Common operators (methods) on immutable collections

Operator (method) Description
c1 ++ c2 Creates a new collection by appending the elements in the collection c2 to the collection c1.
c :+ e Returns a new collection with the element e appended to the collection c.
e +: c Returns a new collection with the element e prepended to the collection c.
e :: list Returns a List with the element e prepended to the List named list. (:: works only on List.)
c drop n
c dropWhile p
c filter p
c filterNot p
c head
c tail
c take n
c takeWhile p
The two methods - and -- have been deprecated, so use the filtering methods listed in Table 10-8 to return a new collection with the desired elements removed. Examples of some of these filtering methods are shown here.

The two methods - and -- have been deprecated, so use the filtering methods listed in Table 10-8 to return a new collection with the desired elements removed. Examples of some of these filtering methods are shown here.

Again, this table lists only the most common methods available on immutable collections. There are other methods available, such as the -- method on a Set. See the Scaladoc for your current collection for even more methods.

Maps

Maps have additional methods, as shown in Table 10-11. In this table, the following symbols are used in the first column:

  • m refers to a map
  • mm refers to a mutable map
  • k refers to a key
  • p refers to a predicate (a function that returns true or false)
  • v refers to a map value
  • c refers to a collection

Table 10-11. Common methods for immutable and mutable maps

Map method Description

Methods for immutable maps
m - k Returns a map with the key k (and its corresponding value) removed.
m - (k1, k2, k3) Returns a map with the keys k1, k2, and k3 removed.
m -- c
m -- List(k1, k2)
Returns a map with the keys in the collection removed. (Although List is shown, this can be any sequential collection.)

Methods for mutable maps
 
mm += (k -> v)
mm += (k1 -> v1, k2 -> v2)
Add the key/value pair(s) to the mutable map mm.
mm ++= c
mm ++= List(3 -> "c")
Add the elements in the collection c to the mutable map mm.

mm -= k
mm -= (k1, k2, k3)

Remove map entries from the mutable map mm based on the given key(s).
mm --= c Remove the map entries from the mutable map mm based on the keys in the collection c.

Methods for both mutable and immutable maps
m(k) Returns the value associated with the key k.
m contains k Returns true if the map m contains the key k.
m filter p Returns a map whose keys and values match the condition of the predicate p.
m filterKeys p Returns a map whose keys match the condition of the predicate p.
m get k Returns the value for the key k as Some[A] if the key is found, None otherwise.
m getOrElse(k, d) Returns the value for the key k if the key is found, otherwise returns the default value d.
m isDefinedAt k Returns true if the map contains the key k.
m keys Returns the keys from the map as an Iterable.
m keyIterator Returns the keys from the map as an Iterator.
m keySet Returns the keys from the map as a Set.
m mapValues f Returns a new map by applying the function f to every value in the initial map.
m values Returns the values from the map as an Iterable.
m valuesIterator Returns the values from the map as an Iterator.

For additional methods, see the Scaladoc for the mutable and immutable map classes.

Discussion

As you can see, Scala collection classes contain a wealth of methods (and methods that appear to be operators). Understanding these methods will help you become more productive, because as you understand them, you’ll write less code and fewer loops, and instead write short functions and predicates to work with these methods.