我需要在读取数据文件后将一些字符串值转换为Ints。该字段可能为空,这会在尝试进行转换时导致错误。是否有一种简单的方法可以检查null(或者可以转换为整数的适当值),如果无法转换则返回0? getOrElse似乎是一种可能性,但我无法完成写作工作。我可以写一个可以很容易地完成它的功能,但我希望有更优雅/简洁的方法来做到这一点。
答案 0 :(得分:8)
您可以使用Try
monad(记录为here),其中包含getOrElse
方法:
import scala.util.Try
val zero = Try { "foo".toInt }.getOrElse(0)
val leet = Try { "1337".toInt }.getOrElse(0)
val parseOrZero: String => Int = x => Try(x.toInt) getOrElse 0
val lines = Seq("123", "42", "sdfd", null, "")
lines.map(parseOrZero)
->> res0: Seq[Int] = List(123, 42, 0, 0, 0)
或直播:
lines.map(x => Try(x.toInt) getOrElse 0)
Try
也有一个toOption
方法,如果成功则获得Some(value)
,或者在异常时获得None
。因此,如果您想过滤掉错误的条目而不是返回0
,则可以执行以下操作:
lines.flatMap(x => Try(x.toInt).toOption)
Try
还具有所有有用的monadic转换,如map
和flatMap
,用于链接更多计算。
答案 1 :(得分:1)
仅转换整数值:
val lines = Seq("123", "42", "sdfd", null, "") // read strings from anywhere
val result = lines
.filter(s => Option(s).isDefined) // drop null values
.filter(_.matches("\\d+")) // drop non integer values
.map(Integer.parseInt) // convert to int
result: Seq[Int] = List(123, 42)
或者返回0而不是错误:
val lines = Seq("123", "42", "sdfd", null, "") // read strings from anywhere
def convert(s: String): Int =
Option(s)
.filter(_.matches("\\d+"))
.map(Integer.parseInt)
.getOrElse(0)
val result = lines.map(convert)
result: Seq[Int] = List(123, 42, 0, 0, 0)
答案 2 :(得分:1)
默认toInt
函数会抛出异常,但您可以提供更安全的版本,返回Option
,然后使用getOrElse
def toInt(s: String): Option[Int] =
try {
Some(s.toInt)
} catch {
case e: Exception => None
}
toInt("42").getOrElse(0) // 42
toInt("foo").getOrElse(0) // 0
或者,您可以使用scalaz
,parseInt
方法在String
上提供Validation[NumberFormatException, Int]
方法,返回Option
,您可以将其转换为"42".parseInt.toOption.getOrElse(0) // 42
"foo".parseInt.toOption.getOrElse(0) // 0
。例如:
{{1}}