Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pattern match int strings?

I'm trying to figure out what the best way to pattern match a string representation of an int in Scala. What I really want to be able to do is something like this:

"1234" match {
  // Some cases
  case "five" => 5
  case Int(i) => i // Fails
  case _ => throw new RuntimeException()
}

One approach is this, using a regular expression. A potential problem with this is that it won't detect if the integer is too large to fit in an int.

val ISINT = "^([+-]?\\d+)$".r

"1234" match {
  case "five" => 5
  case ISINT(t) => t.toInt
  case _ => throw new RuntimeException()
}

Another approach uses a toInt function that returns an Option (borrowed from this blog post). This is nice because it makes the standard library figure out whether the string contains an integer. The problem is that it forces me to nest my logic where I think it should be flat.

def toInt(s: String): Option[Int] = {
  try {
    Some(s.toInt)
  } catch {
    case e: Exception => None
  }
}

"1234" match {
  case "five" => 5
  case t => toInt(t) match {
    case Some(i) => i
    case None => throw new RuntimeException()
  }
}
like image 274
Brian McCutchon Avatar asked Mar 23 '17 16:03

Brian McCutchon


1 Answers

You can define a custom extractor like this

object Int { 
  def unapply(s: String): Option[Int] = util.Try(s.toInt).toOption 
}

And use it like you wanted to

"1234" match {
  // Some cases
  case "five" => 5
  case Int(i) => i // works :)
  case _ => throw new RuntimeException()
}
like image 182
Jasper-M Avatar answered Nov 12 '22 17:11

Jasper-M