1

I need to use bunch of match case in scala, how do I use for or if inside the match case, so for example:

import scala.util.Random

val x = Random.nextInt(30)
val result = match x {
case 0 to 10 => bad
case 11 to 20 => average
case 20 to 30 => cool
}

first question is how do I do that instead of using floor, ceil, round or other math stuff?

secondly, for string value, in php we could easily use if (x == 'some')||(x == 'thing'){result} but how this could worked in scala match case?

for example when val x is random A to I:

val result = match x {
case A || B || C => bad
case D || E || F => average
case G || H || I => cool
}

Thanks!

Deden Bangkit
  • 598
  • 1
  • 5
  • 19
  • 1
    Possible duplicate of [How can I pattern match on a range in Scala?](http://stackoverflow.com/questions/3160888/how-can-i-pattern-match-on-a-range-in-scala) – Yuval Itzchakov Oct 23 '16 at 12:36
  • But it's different @YuvalItzchakov my question also include string, and I think Pamu's answer is much better than using if state – Deden Bangkit Oct 23 '16 at 12:43
  • The answers there don't use `if-else` expressions. Also, from viewing how you can use guards with integers, you can deduce how to do the same for strings. – Yuval Itzchakov Oct 23 '16 at 12:45

2 Answers2

4

Pattern matching using Guards can help you do this

val x = Random.nextInt(30)

val result = x match {
 case x if x > 0 && x <= 10 => "bad"
 case x if x > 11 &&  x <= 20 => "average"
 case x if x > 20 && x <= 30 => "cool"
 case _ => "no idea"
}

For strings you can do this

val str = "foo"

val result = str match {
 case "foo" => "found foo"
 case "bar" => "found bar"
 case _ => "found some thing"
}

You can use | as well

val result = str match {
  case "foo" | "bar" => "match"
  case _ => "no match"
}

Scala REPL

scala> :paste
// Entering paste mode (ctrl-D to finish)

val x = Random.nextInt(30)

val result = x match {
 case x if x > 0 && x <= 10 => "bad"
 case x if x > 11 &&  x <= 20 => "average"
 case x if x > 20 && x <= 30 => "cool"
 case _ => "no idea"
}

// Exiting paste mode, now interpreting.

x: Int = 13
result: String = average
Nagarjuna Pamu
  • 14,737
  • 3
  • 22
  • 40
4

Here's an alternative that resembles more closely your pseudo-code:

val x:Int  

val result = x match {
  case x if (1 to 10).contains(x) => "bad"
  case x if (11 to 20).contains(x) => "average"
  case x if (21 to 30).contains(x) => "cool"
  case _ => "unknown"
}


val y:String 

val result = y match  {
    case "A" | "B" | "C" => "bad"
    case "D" | "E" | "F" => "average"
    case "G" | "H" | "I" => "cool"
    case _ => "unknown"
}

It would be more convenient to treat the alphabetic scores as characters in order to take advantage of ranges as in the first example:

val z:Char 

val result = z match {
  case x if ('A' to 'C').contains(x) => "bad"
  case x if ('D' to 'F').contains(x) => "average"
  case x if ('G' to 'I').contains(x) => "cool"
  case _ => "unknown"
}
maasg
  • 37,100
  • 11
  • 88
  • 115