web-dev-qa-db-ja.com

Scala-Array [String]をArray [Double]に変換します

私は関数型プログラミング言語の初心者であり、大学のプロジェクトではScalaで学習しています。

これは単純に思えるかもしれませんが、オンラインでこれを行うための十分なヘルプを見つけることができないか、これを行う簡単な方法があります。どのようにしてArray [String]をArray [Double]に変換できますか? REPLに読み込まれたときに文字列値として解釈されるCSVファイルがあります(ファイルの各行には整数値と文字列値が混在しています)。これはタイプ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ファイルの各行を二重配列に変換するために、私は疑似定義のみを作成しました。

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
}

どんなアイデアでも大歓迎です。お時間をいただきありがとうございます。

14

maptoDoubleと一緒に使用したい場合があります。

values.map(x => x.toDouble)

またはもっと簡潔に:

values.map(_.toDouble)

また、double以外の文字列のフォールバックについては、Tryモナド(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)
}
25
Ben Reich

@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の結果をパターンマッチングすることができます。これは、SuccessまたはFailureのいずれかであり、getを呼び出したり、他の方法でラップしたりする必要はありません。結果。

Mauricio Linharesの好意によるTryの詳細については、次のとおりです。 https://mauricio.github.io/2014/02/17/scala-one-try-and-the-m-Word.html

3
Joseph Sawyer

すべての文字列を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
  }
})
3

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)
1
Xavier Guihot