Scala control structure examples (if/then, match/case, for, while, try/catch)

This post contains a collection of Scala control structures examples. I initially created most of these in the process of writing the Scala Cookbook. Unlike the Cookbook, I don’t describe them much here, I just show the examples, mostly as a reference for myself (and anyone else that can benefit from them).

if/then control structures:

Here are some examples of the Scala if/then control structure:

if (a == b) doSomething()

if (a == b) doSomething() else doSomethingElse()

if (a == b) {
  doSomething()
} else {
  doSomethingElse()
}

if (test) doA
else if (test) doB
else if (test) doC
else doD

// equality operators
x < y
x > y
x == y
x != y
x >= y
x <= y
&&
||

Because if/then returns a value, you can use it like a Java ternary operator:

// using 'if' like a ternary operator
val absValue = if (a < 0) -a else a                              // ternary
println(if (i == 0) "a" else "b")                                // in println
hash = hash * prime + (if (name == null) 0 else name.hashCode)   // in equation
def abs(x: Int) = if (x >= 0) x else -x                          // as a method body

while loop examples

var i = 0
while (i < array.length) {
  println(array(i))
  i += 1
}

while (hungry) {
  println("Me hungry")
  hungry = getHungerStatus
}

for loop examples

// simple for loops
for (arg <- args) println(arg)
for (i <- 0 to 5) println(i)
for (i <- 0 to 10 by 2) println(i)

// for loop with multiple counters:
scala> for (i <- 1 to 2; j <- 1 to 2) printf("i = %d, j = %d\n", i, j)
i = 1, j = 1
i = 1, j = 2
i = 2, j = 1
i = 2, j = 2

// print all even numbers by adding a 'guard'
scala> for (i <- 1 to 10 if i % 2 == 0) println(i)
2
4
6
8
10

// multiple guards
for {
    file <- files
    if passesFilter1(file)   // guard
    if passesFilter2(file)   // guard
} doSomething(file)

// for loop with guard and yield
for {
  file <- files 
  if hasSoundFileExtension(file)
  if !soundFileIsLong(file)
} yield file

// more for loops with 'yield'
val a = Array("apple", "banana", "orange")        // Array(apple, banana, orange)
val newArray = for (e <- a) yield e.toUpperCase   // Array(APPLE, BANANA, ORANGE)

val a = Array(1, 2, 3, 4, 5)     // Array(1, 2, 3, 4, 5)
for (e <- a) yield e             // Array(1, 2, 3, 4, 5)
(e <- a) yield e * 2             // Array(2, 4, 6, 8, 10)
for (e <- a) yield e % 2         // Array(1, 0, 1, 0, 1)
for (e <- a if e > 2) yield e    // Array(3, 4, 5)

match/case examples

i match {
  case 1  => println("January")
  case 2  => println("February")
  case 3  => println("March")
  case 4  => println("April")
  case 5  => println("May")
  case 6  => println("June")
  case 7  => println("July")
  case 8  => println("August")
  case 9  => println("September")
  case 10 => println("October")
  case 11 => println("November")
  case 12 => println("December")
  // catch the default with a variable so you can print it
  case whoa  => println("Unexpected case: " + whoa.toString)
}

// assign the match result to a value
val month = i match {
  case 1  => "January"
  case 2  => "February"
  case 3  => "March"
  case 4  => "April"
  case 5  => "May"
  case 6  => "June"
  case 7  => "July"
  case 8  => "August"
  case 9  => "September"
  case 10 => "October"
  case 11 => "November"
  case 12 => "December"
  case _  => "Invalid month"  // the default, catch-all
}

match is incredibly flexible:

def getClassAsString(x: Any):String = x match {
  case s: String => s + " is a String"
  case i: Int => "Int"
  case f: Float => "Float"
  case l: List[_] => "List"
  case p: Person => "Person"
  case _ => "Unknown"
}

// multiple int values per case
val evenOrOdd = i match {
  case 1 | 3 | 5 | 7 | 9 => println("odd")
  case 2 | 4 | 6 | 8 | 10 => println("even")
}

// multiple string values per case
val cmd = "stop"
cmd match {
  case "start" | "go" => println("starting")
  case "stop" | "quit" | "exit" => println("stopping")
  case _ => println("doing nothing")
}

// match as the body of a method
def istrue(a: Any) = a match {
  case 0 | "" => false
  case _ => true
}

// assign the 'default' case to a variable
i match {
  case 0 => println("1")
  case 1 => println("2")
  case whoa => println("You gave me: " + whoa)
}

// use 'if' expressions in case statements
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: " + a)
  case c if 20 to 29 contains c => println("20-29 range: " + a)
  case _ => println("Hmmm...")
}

count 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")
}

// reference class fields in your 'if' statements:
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 x => doNothing(x)
}

// extract fields from case classes and use those in your guards ('if' statements)
def speak(p: Person) = p match {
  case Person(name) if name == "Fred" => println("Yubba dubbo doo")
  case Person(name) if name == "Bam Bam" => println("Bam bam!")
  case _ => println("Huh?")
}

// using a List in a match expression
def sumAll(list: List[Int]): Int = list match {
  case Nil => 1
  case n :: rest => n + sumAll(rest)
}

// Option/Some/None in a match
toInt(someString) match {
  case Some(i) => println(i)
  case None => println("That didn't work.")
}

Scala try/catch syntax

try {
  openAndReadAFile(filename)
} catch {
  case e: FileNotFoundException => println("Couldn't find that file.")
  case e: IOException => println("Had an IOException trying to read that file")
  case _ => println("Got some other kind of exception")
}

Summary

I hope this collection of Scala control structure examples (if/then/else, while, match/case, try/catch) has been helpful. I’ll try to keep adding more examples here as time goes by.