There’s a nice Scala Set
tip in the book, Functional Programming Patterns in Scala and Clojure. The tip is this:
You can use a Scala
Set
as a predicate to a function.
Note that a predicate is just a function that returns a Boolean
value.
Examples
The author explains this with the following examples. First, create a Set
named isVowel
, and then show how it can be called just like a method that returns a Boolean
value:
scala> val isVowel = Set('a', 'e', 'i', 'o', 'u') isVowel: scala.collection.immutable.Set[Char] = Set(e, u, a, i, o) scala> isVowel('a') res0: Boolean = true scala> isVowel('b') res1: Boolean = false
That’s cool. It looks like isVowel
is a method or function, but it’s really a Set
.
Next, the author shows us how to put this feature to use. First, define a method named vowelsInString
:
scala> def vowelsInString(string: String) = string.filter(isVowel).toSet vowelsInString: (string: String)scala.collection.immutable.Set[Char]
Notice how isVowel
is passed as a predicate to the filter
method. That’s a nice feature.
How it works
If you’re not comfortable with how that code works, here’s a quick explanation:
string.filter(isVowel)
returns all the vowels from the givenString
.- The
toSet
method reduces that list of vowels by removing all duplicates. This is a nice feature of aSet
that I wrote about in the Scala Cookbook; by converting a sequence to aSet
, you eliminate the duplicates.
Finally, you can see how the code works with a real String
:
scala> vowelsInString("united states") res2: scala.collection.immutable.Set[Char] = Set(u, i, e, a)
So this is a nice thing to remember:
If you want to filter a collection by testing that collection against a set of known elements, use a
Set
as shown in this example.
Other Scala collection methods take a predicate
Other Scala collection methods take a predicate. For instance, the count
method takes a predicate:
scala> "united states".count(isVowel) res3: Int = 5
The filterNot
method also takes a predicate:
scala> "united states".filterNot(isVowel).toSet res4: scala.collection.immutable.Set[Char] = Set(s, n, t, , d)
See the Scaladoc for your current collection class to find many other methods that take a predicate.