web-dev-qa-db-ja.com

Scala:文字列をIntまたはNoneに変換します

Xmlフィールドから数値を取得しようとしています

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

via

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

ただし、xmlに値がない場合もあります。テキストは""そして、これはJava.lang.NumberFormatExceptionをスローします。

IntまたはNoneを取得するクリーンな方法は何ですか?

37
doub1ejack
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
65

受け入れられた回答に続く使用法に関するサイドノートの詳細。 import scala.util.Tryの後、検討する

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

または同様ですが、import Java.lang.NumberFormatExceptionの後に、整数値に変換する際に関連する例外のみに対処するもう少し精巧な形式で、

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

したがって、

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

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

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

Scala 2.13導入 String::toIntOption

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

これを行う別の方法は、独自の関数を記述する必要がなく、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 いいブログ投稿 件名。)

5
Caoilte