如何查找 Scala String 是否可解析为 Double ?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9542126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:57:04  来源:igfitidea点击:

How to find if a Scala String is parseable as a Double or not?

scala

提问by chuck taylor

Suppose that I have a string in scala and I want to try to parse a double out of it.

假设我在 Scala 中有一个字符串,并且我想尝试从中解析一个双精度值。

I know that, I can just call toDoubleand then catch the java num format exception if this fails, but is there a cleaner way to do this? For example if there was a parseDoublefunction that returned Option[Double]this would qualify.

我知道,toDouble如果失败,我可以调用然后捕获 java num 格式异常,但是有没有更简洁的方法来做到这一点?例如,如果有一个parseDouble返回Option[Double]this的函数就符合条件。

I don't want to put this in my own code if it already exists in the standard library and I am just looking for it in the wrong place.

如果它已经存在于标准库中并且我只是在错误的地方寻找它,我不想把它放在我自己的代码中。

Thanks for any help you can provide.

感谢您的任何帮助,您可以提供。

回答by Luigi Plinge

For Scala 2.13+ see Xavier's answer below. Apparently there's a toDoubleOptionmethod now.

对于 Scala 2.13+,请参阅下面 Xavier 的回答。显然toDoubleOption现在有一个方法。

For older versions:

对于旧版本:

def parseDouble(s: String) = try { Some(s.toDouble) } catch { case _ => None }


Fancy version (edit: don't do this except for amusement value; I was a callow youth years ago when I used to write such monstrosities):

花哨的版本(编辑:除了娱乐价值,不要这样做;多年前我曾经写过这样的怪物时我还是个傻子):

case class ParseOp[T](op: String => T)
implicit val popDouble = ParseOp[Double](_.toDouble)
implicit val popInt = ParseOp[Int](_.toInt)
// etc.
def parse[T: ParseOp](s: String) = try { Some(implicitly[ParseOp[T]].op(s)) } 
                                   catch {case _ => None}

scala> parse[Double]("1.23")
res13: Option[Double] = Some(1.23)

scala> parse[Int]("1.23")
res14: Option[Int] = None

scala> parse[Int]("1")
res15: Option[Int] = Some(1)

回答by missingfaktor

Scalaz provides an extension method parseDoubleon Strings, which gives a value of type Validation[NumberFormatException, Double].

ScalazparseDoubleStrings上提供了一个扩展方法,它给出了一个类型的值Validation[NumberFormatException, Double]

scala> "34.5".parseDouble
res34: scalaz.Validation[NumberFormatException,Double] = Success(34.5)

scala> "34.bad".parseDouble
res35: scalaz.Validation[NumberFormatException,Double] = Failure(java.lang.NumberFormatException: For input string: "34.bad")

You can convert it to Optionif so required.

Option如果需要,您可以将其转换为。

scala> "34.bad".parseDouble.toOption
res36: Option[Double] = None

回答by Jeff Schwab

scala> import scala.util.Try
import scala.util.Try

scala> def parseDouble(s: String): Option[Double] = Try { s.toDouble }.toOption
parseDouble: (s: String)Option[Double]

scala> parseDouble("3.14")
res0: Option[Double] = Some(3.14)

scala> parseDouble("hello")
res1: Option[Double] = None

回答by Don Mackenzie

You could try using util.control.Exception.catchingwhich returns an Eithertype.

您可以尝试使用util.control.Exception.catchingwhich 返回一个Either类型。

So using the following returns a Left wrapping a NumberFormatExceptionor a Right wrapping a Double

因此,使用以下返回左环绕 aNumberFormatException或右环绕 aDouble

import util.control.Exception._

catching(classOf[NumberFormatException]) either "12.W3".toDouble

回答by Rex Kerr

Unfortunately, this isn't in the standard library. Here's what I use:

不幸的是,这不在标准库中。这是我使用的:

class SafeParsePrimitive(s: String) {
  private def nfe[T](t: => T) = {
    try { Some(t) }
    catch { case nfe: NumberFormatException => None }
  }
  def booleanOption = s.toLowerCase match {
    case "yes" | "true" => Some(true)
    case "no" | "false" => Some(false)
    case _ => None
  }
  def byteOption = nfe(s.toByte)
  def doubleOption = nfe(s.toDouble)
  def floatOption = nfe(s.toFloat)
  def hexOption = nfe(java.lang.Integer.valueOf(s,16))
  def hexLongOption = nfe(java.lang.Long.valueOf(s,16))
  def intOption = nfe(s.toInt)
  def longOption = nfe(s.toLong)
  def shortOption = nfe(s.toShort)
}
implicit def string_parses_safely(s: String) = new SafeParsePrimitive(s)

回答by Xavier Guihot

Scala 2.13introduced String::toDoubleOption:

Scala 2.13介绍String::toDoubleOption

"5.7".toDoubleOption                // Option[Double] = Some(5.7)
"abc".toDoubleOption                // Option[Double] = None
"abc".toDoubleOption.getOrElse(-1d) // Double = -1.0

回答by Fixpoint

There's nothing like this not only in Scala, but even in basic Java.

不仅在 Scala 中,甚至在基本的 Java 中都没有这样的东西。

Here's a piece code that does it without exceptions, though:

不过,这里有一段代码可以毫无例外地做到这一点:

def parseDouble(s: String)(implicit nf: NumberFormat) = {
    val pp = new ParsePosition(0)
    val d = nf.parse(s, pp)
    if (pp.getErrorIndex == -1) Some(d.doubleValue) else None
}

Usage:

用法:

implicit val formatter = NumberFormat.getInstance(Locale.ENGLISH)

Console println parseDouble("184.33")
Console println parseDouble("hello, world")

回答by Maverick

I'd usually go with an "in place" Try:

我通常会选择“就地”尝试:

def strTimesTen (s: String) = for (d <- Try(s.toDouble)) yield d * 10

strTimesTen("0.1") match {
    Success(d) => println( s"It is $d" )
    Failure(ex) => println( "I've asked for a number!" )
}

Note, that you can do further calculation in the for and any exception would project into a Failure(ex). AFAIK this is the idiomatic way of handling a sequence of unreliable operations.

请注意,您可以在 for 中进行进一步计算,任何异常都会投射到 Failure(ex) 中。AFAIK 这是处理一系列不可靠操作的惯用方法。