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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28785064/
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 06:56:21  来源:igfitidea点击:

Scala - convert Array[String] to Array[Double]

arraysscalafunctional-programming

提问by Sharadha Jayaraman

I am a newbie to functional programming language and I am learning it in Scala for a University project.

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

This may seem simple, but I am unable to find enough help online for this or a straightforward way of doing this - how can I convert an Array[String] to Array[Double]? I have a CSV file which, when read into the REPL is interpreted as String values (each line of the file has a mix of integer and string values) which would return a type Array[String]. I want to encode the string values with a double/int values to return Array[Double] in order to make the array homogeneous. Is there a straightforward way of doing this? Any guidance will be much appreciated.

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

What I have done until now is:

到目前为止我所做的是:

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

  return items.toArray
}

The format of each line (returned as String[]) is so:

每行的格式(以 String[] 形式返回)如下:

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

And to convert each line in the CSV file into double array, I only have a psuedo definition drafted so:

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

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
}

Any ideas are welcome. Thank you for your time.

欢迎任何想法。感谢您的时间。

回答by Ben Reich

You probably want to use mapalong with toDouble:

您可能想与以下map一起使用toDouble

values.map(x => x.toDouble)

Or more concisely:

或者更简洁:

values.map(_.toDouble)

And for the fallback for non-double strings, you might consider using the Trymonad (in scala.util):

对于非双字符串的回退,您可以考虑使用Trymonad (in scala.util):

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

If you know what each line will look like, you could also do pattern matching:

如果您知道每一行的样子,您还可以进行模式匹配:

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

回答by Lodewijk Bogaards

You mean to convert all strings to double with a fallback to 1.0 for all inconvertible strings? That would be:

您的意思是将所有字符串转换为 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
  }
})

回答by Joseph Sawyer

Expanding on @DaunnC's comment, you can use the Tryutility to do this and pattern match on the result so you can avoid calling getor wrapping your result in an Option:

扩展@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
}

This allows you to pattern match on the result of Try, which is always either a Successor Failure, without having to call getor otherwise wrap your results.

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

Here is some more information on Try courtesy of Mauricio Linhares: https://mauricio.github.io/2014/02/17/scala-either-try-and-the-m-word.html

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

回答by Xavier Guihot

Scala 2.13introduced String::toDoubleOptionwhich used within a maptransformation, can be associated with Option::getOrElseto safely cast Strings into Doubles:

Scala 2.13引入String::toDoubleOptionmap转换中使用的,可以与Option::getOrElse安全地将Strings 转换为Doubles相关联:

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