This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is Recipe 10.17, “How to use filter
to Filter a Scala Collection”
Problem
You want to filter the items in a collection to create a new collection that contains only the elements that match your filtering criteria.
Solution
As listed in Recipe 10.3, “Choosing a Collection Method to Solve a Problem”, a variety of methods can be used to filter the elements of an input collection to produce a new output collection. This recipe demonstrates the filter
method.
To use filter
on your collection, give it a predicate to filter the collection elements as desired. Your predicate should accept a parameter of the same type that the collection holds, evaluate that element, and return true to keep the element in the new collection, or false to filter it out. Remember to assign the results of the filtering operation to a new variable.
A predicate is just a method (or function) that returns a boolean value.
For instance, the following example shows how to create a list of even numbers from an input list using a modulus algorithm:
scala> val x = List.range(1, 10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9) // create a list of all the even numbers in the list scala> val evens = x.filter(_ % 2 == 0) evens: List[Int] = List(2, 4, 6, 8)
As shown, filter
returns all elements from a sequence that return true when your function/predicate is called. There’s also a filterNot
method that returns all elements from a list for which your function returns false.
Tip: You can think of
filter
as meaning retain.
Discussion
The main methods you can use to filter a Scala collection are listed in Recipe 10.3 of the Scala Cookbook, and are repeated here for your convenience:
collect
diff
distinct
drop
dropWhile
filter
filterNot
find
foldLeft
foldRight
head
headOption
init
intersect
last
lastOption
reduceLeft
reduceRight
remove
slice
tail
take
takeWhile
union
Unique characteristics of filter
compared to these other methods include:
filter
walks through all of the elements in the collection; some of the other methods stop before reaching the end of the collectionfilter
lets you supply a predicate to filter the elements
How you filter the elements in your collection is entirely up to your algorithm. The following examples show a few ways to filter a list of strings:
scala> val fruits = Set("orange", "peach", "apple", "banana") fruits: scala.collection.immutable.Set[java.lang.String] = Set(orange, peach, apple, banana) scala> val x = fruits.filter(_.startsWith("a")) x: scala.collection.immutable.Set[String] = Set(apple) scala> val y = fruits.filter(_.length > 5) y: scala.collection.immutable.Set[String] = Set(orange, banana)
Your filtering function can be as complicated as needed. When your algorithm gets long, you can pass a multiline block of code into filter
:
scala> val list = "apple" :: "banana" :: 1 :: 2 :: Nil list: List[Any] = List(apple, banana, 1, 2) scala> val strings = list.filter { | case s: String => true | case _ => false | } strings: List[Any] = List(apple, banana)
You can also put your algorithm in a separate method (or function) and then pass it into filter
:
def onlyStrings(a: Any) = a match { case s: String => true case _ => false } val strings = list.filter(onlyStrings)
The following example demonstrates that you can filter a list as many times as needed:
def getFileContentsWithoutBlanksComments(canonicalFilename: String): List[String] = { io.Source.fromFile(canonicalFilename) .getLines .toList .filter(_.trim != "") .filter(_.charAt(0) != '#') }
The two keys to using filter
are:
- Your algorithm should return true for the elements you want to keep and false for the other elements
- Remember to assign the results of the filter method to a new variable;
filter
doesn’t modify the collection it’s invoked on
See Also
- The
collect
method can also be used as a filtering method. Because it uses partial functions, it’s described in detail in Recipe 9.8, “Creating Partial Functions”.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |