Scala - Options



Scala Option[ T ] is a container for zero or one element of a given type. An Option[T] can be either Some[T] or None object, which represents a missing value. For instance, the get method of Scala's Map produces Some(value) if a value corresponding to a given key has been found, or None if the given key is not defined in the Map.

Option type is used frequently in Scala programs and you can compare this with the null value available in Java which indicate no value. For example, the get method of java.util.HashMap returns either a value stored in the HashMap, or null if no value was found.

Let's say we have a method that retrieves a record from the database based on a primary key.

def findPerson(key: Int): Option[Person]

The method will return Some[Person] if the record is found but None if the record is not found. Let us follow the following program.

Example

object Demo {
   def main(args: Array[String]) {
      val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
      
      println("capitals.get( \"France\" ) : " +  capitals.get( "France" ))
      println("capitals.get( \"India\" ) : " +  capitals.get( "India" ))
   }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Output

capitals.get( "France" ) : Some(Paris)
capitals.get( "India" ) : None

The most common way to take optional values apart is through a pattern match. For example try the following program.

Example

object Demo {
   def main(args: Array[String]) {
      val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
      
      println("show(capitals.get( \"Japan\")) : " + show(capitals.get( "Japan")) )
      println("show(capitals.get( \"India\")) : " + show(capitals.get( "India")) )
   }
   
   def show(x: Option[String]) = x match {
      case Some(s) => s
      case None => "?"
   }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Output

show(capitals.get( "Japan")) : Tokyo
show(capitals.get( "India")) : ?

Using getOrElse() Method

Following is the example program to show how to use getOrElse() method to access a value or a default when no value is present.

Example

object Demo {
   def main(args: Array[String]) {
      val a:Option[Int] = Some(5)
      val b:Option[Int] = None 
      
      println("a.getOrElse(0): " + a.getOrElse(0) )
      println("b.getOrElse(10): " + b.getOrElse(10) )
   }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Output

a.getOrElse(0): 5
b.getOrElse(10): 10

Using isEmpty() Method

Following is the example program to show how to use isEmpty() method to check if the option is None or not.

Example

object Demo {
   def main(args: Array[String]) {
      val a:Option[Int] = Some(5)
      val b:Option[Int] = None 
      
      println("a.isEmpty: " + a.isEmpty )
      println("b.isEmpty: " + b.isEmpty )
   }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Example

a.isEmpty: false
b.isEmpty: true

Using map() Method

The map() method allows you to transform an Option value by applying a function to it. If the Option is Some, the function is applied to the contained value. If the Option is None, None is returned.

Example

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.map(_ * 2): " + a.map(_ * 2))
      println("b.map(_ * 2): " + b.map(_ * 2))
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

a.map(_ * 2): Some(10)
b.map(_ * 2): None

Using flatMap() Method

The flatMap() method is similar to map(), but it is used when the function applied returns an Option. This is used for chaining operations that return Option values. Try following example for using flatMap() method -

Example

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.flatMap(x => Some(x * 2)): " + a.flatMap(x => Some(x * 2)))
      println("b.flatMap(x => Some(x * 2)): " + b.flatMap(x => Some(x * 2)))
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

a.flatMap(x => Some(x * 2)): Some(10)
b.flatMap(x => Some(x * 2)): None

Using filter() Method

The filter() method allows you to filter the value inside an Option using a predicate function. If the Option is Some and the predicate is satisfied, the original Option is returned. Otherwise, None is returned. Try following example for using filter() method -

Example

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.filter(_ > 3): " + a.filter(_ > 3))
      println("a.filter(_ > 8): " + a.filter(_ > 8))
      println("b.filter(_ > 3): " + b.filter(_ > 3))
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

a.filter(_ > 3): Some(5)
a.filter(_ > 8): None
b.filter(_ > 3): None

Using foreach() Method

Using the foreach() method, you can apply a function to the value inside an Option if it is Some. If the Option is None, nothing happens. This method is used for side effects. Try following example for using foreach() method -

Example

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      a.foreach(x => println("Value of a: " + x))
      b.foreach(x => println("Value of b: " + x))
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

Value of a: 5

Using fold() Method

Using the fold() method, you can handle both Some and None cases in a single expression. It takes two functions: one for handling the None case and one for handling the Some case. Try following example for using fold() method -

Example

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.fold(0)(_ * 2): " + a.fold(0)(_ * 2))
      println("b.fold(0)(_ * 2): " + b.fold(0)(_ * 2))
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

a.fold(0)(_ * 2): 10
b.fold(0)(_ * 2): 0

Scala Option Methods

Following are the important methods which you can use while playing with Options. For a complete list of methods available, please check official documentation of Scala.

Sr.No Methods with Description
1

def get: A

Returns the option's value.

2

def isEmpty: Boolean

Returns true if the option is None, false otherwise.

3

def productArity: Int

The size of this product. For a product A(x_1, ..., x_k), returns k

4

def productElement(n: Int): Any

The nth element of this product, 0-based. In other words, for a product A(x_1, ..., x_k), returns x_(n+1) where 0 < n < k.

5

def exists(p: (A) => Boolean): Boolean

Returns true if this option is nonempty and the predicate p returns true when applied to this Option's value. Otherwise, returns false.

6

def filter(p: (A) => Boolean): Option[A]

Returns this Option if it is nonempty and applying the predicate p to this Option's value returns true. Otherwise, return None.

7

def filterNot(p: (A) => Boolean): Option[A]

Returns this Option if it is nonempty and applying the predicate p to this Option's value returns false. Otherwise, return None.

8

def flatMap[B](f: (A) => Option[B]): Option[B]

Returns the result of applying f to this Option's value if this Option is nonempty. Returns None if this Option is empty.

9

def foreach[U](f: (A) => U): Unit

Apply the given procedure f to the option's value, if it is nonempty. Otherwise, do nothing.

10

def getOrElse[B >: A](default: => B): B

Returns the option's value if the option is nonempty, otherwise return the result of evaluating default.

11

def isDefined: Boolean

Returns true if the option is an instance of Some, false otherwise.

12

def iterator: Iterator[A]

Returns a singleton iterator returning the Option's value if it is nonempty, or an empty iterator if the option is empty.

13

def map[B](f: (A) => B): Option[B]

Returns a Some containing the result of applying f to this Option's value if this Option is nonempty. Otherwise return None.

14

def orElse[B >: A](alternative: => Option[B]): Option[B]

Returns this Option if it is nonempty, otherwise return the result of evaluating alternative.

15

def orNull

Returns the option's value if it is nonempty, or null if it is empty.

scala_collections.htm
Advertisements