如何将任何数字转换为Double?

时间:2017-02-24 07:45:16

标签: scala type-conversion

我需要进行一些原始数据解析,并且我被迫使用Any类型。

如果我读取的数据采用任何数字格式(Int / Double / Long / ...),我需要将其转换为Double,否则(例如。String)我需要把它留空。

这就是我提出的:

def extractDouble(expectedNumber: Any): Option[Double] = expectedNumber match {
  case i: Int => Some(i.toDouble)
  case l: Long => Some(l.toDouble)
  case d: Double => Some(d)
  case _ => None
}

这显然看起来不太合适。在Scala中有没有更好的方法来解决这个问题?

5 个答案:

答案 0 :(得分:8)

一旦您在编译时丢失了类型信息,因为它恰好是您的情况,因为您的输入类型是Any作为其要求的一部分,没有比检查expectedNumber更多的选项了运行isInstanceOf

您在提议的解决方案中执行的类型模式匹配会掩盖这一点。我认为这是您案例中最好的解决方案。

但是,有一种替代方法是使用Try并将其转换为Option。例如:

Try(expectedNumber.toString.toDouble).toOption

这在很多方面都是一个肮脏的解决方案(根本没有效率,使用例外来控制流量......)我会定义地使用你的第一种方法

答案 1 :(得分:3)

SQL Fiddle回答:

所示,这当然是可能的

使用java.lang.Number与您的案例类型匹配。

def extractDouble(x: Any): Option[Double] = x match {
  case n: java.lang.Number => Some(n.doubleValue())
  case _ => None
}

请注意,这也适用于BigDecimalBigInteger的实例,无论是scala.math.BigDecimal还是java.math.BigDecimal

答案 2 :(得分:1)

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

Scala is a string parseable as a double

答案 3 :(得分:1)

我正在使用OP的解决方案一段时间。但是在遇到一些稍微损坏的数据输入时,我随后改为OP解决方案和Try解决方案的组合。

  def extractDouble(expectedNumber: Any): Option[Double] = expectedNumber match {
    case i: Int => Some(i.toDouble)
    case l: Long => Some(l.toDouble)
    case d: Double => Some(d)
    case s: String => Try(s.trim.toDouble).toOption
    case _ => None
  } 

case s:String行可能会为您节省一些调试工作,如果您正在处理大而且可能混乱的数据,那么可能会让您感到沮丧

答案 4 :(得分:0)

Scala 2.13开始,我们可以将expectedNumber: Any转换为String之后应用新的String::toDoubleOption

def extractDouble(expectedNumber: Any): Option[Double] =
  expectedNumber.toString.toDoubleOption

例如:

extractDouble(12.56d)  // Option[Double] = Some(12.56)
extractDouble(12)      // Option[Double] = Some(12.0)
extractDouble(12L)     // Option[Double] = Some(12.0)
extractDouble("hello") // Option[Double] = None