Scala: convert string to Int or None

45,886

Solution 1

scala> import scala.util.Try
import scala.util.Try

scala> def tryToInt( s: String ) = Try(s.toInt).toOption
tryToInt: (s: String)Option[Int]

scala> tryToInt("123")
res0: Option[Int] = Some(123)

scala> tryToInt("")
res1: Option[Int] = None

Solution 2

Scala 2.13 introduced String::toIntOption:

"5".toIntOption                 // Option[Int] = Some(5)
"abc".toIntOption               // Option[Int] = None
"abc".toIntOption.getOrElse(-1) // Int = -1

Solution 3

More of a side note on usage following accepted answer. After import scala.util.Try, consider

implicit class RichOptionConvert(val s: String) extends AnyVal {
  def toOptInt() = Try (s.toInt) toOption
}

or similarly but in a bit more elaborated form that addresses only the relevant exception in converting onto integral values, after import java.lang.NumberFormatException,

implicit class RichOptionConvert(val s: String) extends AnyVal {
  def toOptInt() = 
    try { 
      Some(s.toInt) 
    } catch { 
      case e: NumberFormatException => None 
    }
}

Thus,

"123".toOptInt
res: Option[Int] = Some(123)

Array(4,5,6).mkString.toOptInt
res: Option[Int] = Some(456)

"nan".toInt
res: Option[Int] = None

Solution 4

Here's another way of doing this that doesn't require writing your own function and which can also be used to lift to Either.

scala> import util.control.Exception._
import util.control.Exception._

scala> allCatch.opt { "42".toInt }
res0: Option[Int] = Some(42)

scala> allCatch.opt { "answer".toInt }
res1: Option[Int] = None

scala> allCatch.either { "42".toInt }
res3: scala.util.Either[Throwable,Int] = Right(42)

(A nice blog post on the subject.)

Share:
45,886

Related videos on Youtube

doub1ejack
Author by

doub1ejack

Updated on July 09, 2022

Comments

  • doub1ejack
    doub1ejack almost 2 years

    I am trying to get a number out of an xml field

    ...
    <Quantity>12</Quantity>
    ...
    

    via

    Some((recipe \ "Main" \ "Quantity").text.toInt)
    

    Sometimes there may not be a value in the xml, though. The text will be "" and this throws an java.lang.NumberFormatException.

    What is a clean way to get either an Int or a None?

  • Rex Kerr
    Rex Kerr about 10 years
    If you are parsing a lot of empty strings, you might want to catch them explicitly instead of throwing an exception every time: if (s.isEmpty) None else Try(s.toInt).toOption.
  • jwvh
    jwvh about 8 years
    Your final example won't give that result. Looks like a cut-n-paste error.
  • Aydin Gerek
    Aydin Gerek about 8 years
    oops. thanks. only changed it because the left was annoyingly long.
  • starscream_disco_party
    starscream_disco_party almost 6 years
    Shouldn't "nan".toInt be "nan".toOptInt?