将字符串的scala列表转换为双打列表,同时丢弃不可转换的字符串

Sim*_*ish 2 scala

我正在尝试将字符串列表解析为数字格式,同时忽略任何无法解析的字符串.这是我的尝试,但我不禁认为这是一个足够普遍的模式,必须有一个比调用2个地图和过滤器更好的方法.有人可以建议一种更规范的方法吗?也许使用某种部分功能?谢谢!

val stringList = List("1","2","foo","4")
val parsed = stringList.map(s => scala.util.Try(s.toDouble)).filter(_.isSuccess).map(_.get)
Run Code Online (Sandbox Code Playgroud)

输出:

stringList: List[String] = List(1, 2, foo, 4)
scala> parsed: List[Double] = List(1.0, 2.0, 4.0)
Run Code Online (Sandbox Code Playgroud)

Vic*_*roz 9

flatMap 帮助:

scala>  List("1","2","foo","4").flatMap(s => scala.util.Try(s.toDouble).toOption)
res0: List[Double] = List(1.0, 2.0, 4.0)
Run Code Online (Sandbox Code Playgroud)


Rex*_*err 5

请记住,异常会让您失望很多.因此,尽管该Try方法有效,但如果大多数事情都不是数字,那么它将无法很快地运行.

你可以写一个正则表达式来挑选可能是双打的东西:

val D = """(-?[0-9]+(?:\.[0-9]+)(?:[eE]?[+-]?[0-9]+)?)""".r
Run Code Online (Sandbox Code Playgroud)

然后你只会尝试解析实际上是双打的东西:

val xs = List("1", "2", "foo", "4")
xs.collect{
  case D(x) => x.toDouble
  case "NaN" => Double.NaN
  case "Infinity" => Double.PositiveInfinity
  case "-Infinity" => Double.NegativeInfinity
}
Run Code Online (Sandbox Code Playgroud)

根据应用程序,当存在大量非Double条目时(例如,在您的示例中为1/4),它大约快10-60倍.