3.13. Adding if Expressions (Guards) to Case Statements

Problem

You want to add qualifying logic to a case statement in a match expression, such as allowing a range of numbers, or matching a pattern, but only if that pattern matches some additional criteria.

Solution

Add an if guard to your case statement. Use it to match a range of numbers:

i match {
  case a if 0 to 9 contains a => println("0-9 range: " + a)
  case b if 10 to 19 contains b => println("10-19 range: " + b)
  case c if 20 to 29 contains c => println("20-29 range: " + c)
  case _ => println("Hmmm...")
}

Use it to match different values of an object:

num match {
  case x if x == 1 => println("one, a lonely number")
  case x if (x == 2 || x == 3) => println(x)
  case _ => println("some other value")
}

You can reference class fields in your if guards. Imagine here that x is an instance of a Stock class that has symbol and price fields:

stock match {
  case x if (x.symbol == "XYZ" && x.price < 20) => buy(x)
  case x if (x.symbol == "XYZ" && x.price > 50) => sell(x)
  case _ => // do nothing
}

You can also extract fields from case classes and use those in your guards:

def speak(p: Person) = p match {
  case Person(name) if name == "Fred" => println("Yubba dubba doo")
  case Person(name) if name == "Bam Bam" => println("Bam bam!")
  case _ => println("Watch the Flintstones!")
}

Discussion

You can use this syntax whenever you want to add simple matches to your case statements on the left side of the expression.

Note that all of these examples could be written ...

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.