【发布时间】:2015-01-03 06:38:48
【问题描述】:
读取数据文件后,我需要将一些字符串值转换为 Ints。该字段可能为空,这将在尝试进行转换时导致错误。是否有一种简单的方法来检查 null (或可以转换为整数的适当值),如果不能转换则只返回 0 ? getOrElse 似乎是一种可能性,但我不能完全让它工作。我可以编写一个可以轻松完成的函数,但我希望有一种更优雅/更简洁的方法来做到这一点。
【问题讨论】:
标签: scala
读取数据文件后,我需要将一些字符串值转换为 Ints。该字段可能为空,这将在尝试进行转换时导致错误。是否有一种简单的方法来检查 null (或可以转换为整数的适当值),如果不能转换则只返回 0 ? getOrElse 似乎是一种可能性,但我不能完全让它工作。我可以编写一个可以轻松完成的函数,但我希望有一种更优雅/更简洁的方法来做到这一点。
【问题讨论】:
标签: scala
只转换整数值:
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)
【讨论】:
默认的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,它在String 上提供parseInt 方法,该方法返回Validation[NumberFormatException, Int],您可以将其转换为Option。示例:
"42".parseInt.toOption.getOrElse(0) // 42
"foo".parseInt.toOption.getOrElse(0) // 0
【讨论】:
您可以使用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 还具有所有有用的一元转换,例如 map 和 flatMap,用于链接更多计算。
【讨论】: