Scala - 将Array [String]转换为Array [Double]

时间:2015-02-28 18:06:35

标签: arrays scala functional-programming

我是函数式编程语言的新手,我正在Scala中学习大学项目。

这可能看起来很简单,但是我无法在网上找到足够的帮助,或者直接这样做 - 如何将Array [String]转换为Array [Double]?我有一个CSV文件,当读入REPL时被解释为String值(文件的每一行都有整数和字符串值的混合),这将返回一个类型Array [String]。我想用double / int值对字符串值进行编码,以返回Array [Double]以使数组均匀。有这么简单的方法吗?任何指导都将非常感谢。

到目前为止,我所做的是:

def retrieveExamplesFromFile(fileName : String) : Array[Array[String]] = {
  val items = for {
    line <- Source.fromFile(fileName).getLines()
    entries = line.split(",")
    } yield entries

  return items.toArray
}

每一行的格式(以String []形式返回)是这样的:

[[1.0, 2.0, item1], [5, 8.9, item2],....]

要将CSV文件中的每一行转换为双数组,我只能起草一个psuedo定义:

def generateNumbersForStringValues(values : Array[String]) : Array[Double] = {
val line = for(item <- values)
{
    //correct way?
    item.replace("item1", "1.0")
    item.replace("item2", "1.0")    
} 
return //unable to typecast/convert
}

欢迎任何想法。谢谢你的时间。

4 个答案:

答案 0 :(得分:24)

您可能希望将maptoDouble一起使用:

values.map(x => x.toDouble)

或者更简洁:

values.map(_.toDouble)

对于非双字符串的后备,您可以考虑使用Try monad(在scala.util中):

values.map(x => Try(x.toDouble).getOrElse(1.0))

如果你知道每条线的样子,你也可以进行模式匹配:

values map { 
    case Array(a, b, c) => Array(a.toDouble, b.toDouble, 1.0)
}

答案 1 :(得分:3)

你的意思是将所有字符串转换为double,并且对于所有不可转换的字符串,回退到1.0?那将是:

val x = Array(
  Array("1.0", "2.0", "item1"),
  Array("5", "8.9", "item2"))

x.map( _.map { y =>
  try {
    y.toDouble
  } catch {
    case _: NumberFormatException => 1.0
  }
})

答案 2 :(得分:3)

扩展@ DaunnC的评论,您可以使用Try实用程序执行此操作并对结果进行模式匹配,这样您就可以避免调用get或将结果包装在Option中:

import scala.util.{Try, Success, Failure}

def main = {
  val maybeDoubles = Array("5", "1.0", "8.5", "10.0", "item1", "item2")

  val convertDoubles = maybeDoubles.map { x =>
    Try(x.toDouble)
  }

  val convertedArray = convertDoubles.map {
    _ match {
      case Success(res) => res
      case Failure(f) => 1.0
   }
  }

  convertedArray
}

这允许您对Try的结果进行模式匹配,该结果始终为SuccessFailure,而无需调用get或以其他方式包装结果

以下是有关Mauricio Linhares礼貌的更多信息:https://mauricio.github.io/2014/02/17/scala-either-try-and-the-m-word.html

答案 3 :(得分:0)

Scala 2.13引入了String::toDoubleOption,它在map转换中使用,可以与Option::getOrElse关联,以将String s强制转换为Double s :

Array("5", "1.0", ".", "8.5", "int").map(_.toDoubleOption.getOrElse(1d))
// Array[Double] = Array(5.0, 1.0, 1.0, 8.5, 1.0)