Omnipresent Omnipresent - 2 months ago 7
Scala Question

How to use scala switch statement for a class

I am trying to write a function in scala that will return a

Boolean
based on several case statements

def my_func(result : Result) : Boolean = {
labResult match {
case (result.name == "test" && result.value >= 10) => false
//more case statements
}
}


But I'm getting a compile error on the
&&
. What is the way to accomplish this?

Answer

Use guard with extractor

case class Result(name: String, value: Int)

def my_func(result: Result): Boolean = result match {
 case Result(name, value) if name == "test" && value >= 10 => false
}

Its not switch its called as Pattern matching in Scala jargon. Above code is the idiomatic Scala code which has Pattern matching guard with extractor.

Don't forget to give the case where the condition does not hold if not you will get Match Error

case class Result(name: String, value: Int)

def my_func(result: Result): Boolean = result match {
 case Result(name, value) if name == "test" && value >= 10 => false
 case _ => true //if above condition fails to match 
}

If you have extra params then use _ to ignore

case class Result(name: String, value: Int, foo: Int)

def my_func(result: Result): Boolean = result match {
  case Result(name, value, _) if name == "test" && value >= 10 => false
  case _ => true //if above condition fails to match 
}

In the above code we are ignoring foo by using _.

Note we can use multiple _ to ignore multiple parameters. we can use _ in between as well like this Result(name, _, foo). Here we are ignoring value parameter

If Result is not a case class then Parameter extraction during pattern matching does not work So you have to write a Custom extractor for Result class.

Note Scala compiler writes a extractor for you in case of case class. In case of normal class we have to write extractor for pattern matching with extracted parameters to work

class Result (val name: String, val value: Int, val foo: Int)

object Result {
  def unapply(result: Result): Option[(String, Int, Int)] = Some((result.name, result.value, result.foo))
}

def my_func(result: Result): Boolean = result match {
  case Result(name, value, _) if name == "test" && value >= 10 => false
  case _ => true //if above condition fails to match 
}