我正在阅读并解析一个json文件。 json文件的一个字段是Nullable。它返回一串数字或Null。我需要将字符串转换为int。我能够通过以下代码从String转换为Option [Int],但无法从Option [String]转换为Option [Int]
def toInt(userId: String):Option[Int] = {
try {
Some(userId.toInt)
} catch {
case e:Exception => None
}
}
val user = toInt("abc")
我需要做哪些更改?
答案 0 :(得分:12)
import util.Try
def toInt(o: Option[String]): Option[Int] =
o.flatMap(s => Try(s.toInt).toOption)
示例:
scala> toInt(None)
res0: Option[Int] = None
scala> toInt(Some("42"))
res1: Option[Int] = Some(42)
scala> toInt(Some("abc"))
res2: Option[Int] = None
答案 1 :(得分:4)
Option(userId).map(_.toInt)
使用Option
代替Some
。而不是使用map
将其转换为Int
答案 2 :(得分:1)
@Chris Martin和@Michael Zajac的解决方案很好:
import util.Try
def toInt(o: Option[String]): Option[Int] =
o.flatMap(s => Try(s.toInt).toOption)
但是
如果输入数据经常不正确,则它将使NumberFormatException
的生成量增加Try
,这对于垃圾收集器来说是不好的。操作后,它需要利用更多的堆栈跟踪。
这意味着我们应该在这里避免使用scala.util.Try
。
在输入数据经常不正确的情况下,这不是一个简短但性能更高的解决方案:
def toInt(s: Option[String]): Option[Int] = s match {
case None => None
case Some(v) if v.isEmpty => None
case Some(v) => if (v.forall(_.isDigit) || (v.startsWith("-") && v.drop(1).forall(_.isDigit)))
Some(v.toInt)
else
None
}
测试:
scala> toInt(None)
res0: Option[Int] = None
scala> toInt(Some(""))
res1: Option[Int] = None
scala> toInt(Some("42"))
res2: Option[Int] = Some(42)
scala> toInt(Some("-42"))
res3: Option[Int] = Some(-42)
scala> toInt(Some("abc"))
res4: Option[Int] = None
摘要:切勿对控制流使用异常!
答案 3 :(得分:0)
您必须map
Option
对可能包含的值执行某些操作。在代码的上下文中,我会使用flatMap
,因为当前方法返回Option
,因此我们必须展平嵌套Option
的内容。
def toInt(userIdOpt: Option[String]): Option[Int] = userIdOpt flatMap { userId =>
try {
Some(userId.toInt)
} catch {
case e:Exception => None
}
}
scala> val u = Option("2")
u: Option[String] = Some(2)
scala> toInt(u)
res0: Option[Int] = Some(2)
scala> toInt(Some("a"))
res4: Option[Int] = None
我们可以使用Try
缩短此内容。
import scala.util.Try
def toInt(userIdOpt: Option[String]): Option[Int] =
userIdOpt.flatMap(a => Try(a.toInt).toOption)
Try(a.toInt)
会返回Try[Int]
,其成功转化为Success[Int]
,转换失败(不是整数)为Failure[Throwable]
。 Try
有一个非常方便的方法toOption
,它会将Success(a)
转换为Some(a)
,将Failure
转换为None
,这正是我们想要的
答案 4 :(得分:0)
Scala 2.13
引入了String::toIntOption
:
与flatMap
结合使用可提供从Option[String]
投射到Option[Int]
的安全方法:
Option("1").flatMap(_.toIntOption) // Option[Int] = Some(1)
(None: Option[String]).flatMap(_.toIntOption) // Option[Int] = None
Option("abc").flatMap(_.toIntOption) // Option[Int] = None
Option(null: String).flatMap(_.toIntOption) // Option[Int] = None