Reputation: 179
I would like to read csv file in scala.
val rows = ArrayBuffer[Array[String]]()
using(io.Source.fromFile("test.csv")) { source =>
for (line <- source.getLines) {
rows += line.split(",").map(_.trim)
}
}
def using[A <: { def close(): Unit }, B](resource: A)(f: A => B): B =
try {
f(resource)
}finally {
resource.close()
}
I used above code to read csv file.
I get ArrayBuffer(Array[String]) now, but I want to get ArrayBuffer(Array[Double]).
toDouble method is wrong
What's the ideal way to do?
Thank you for your time.
Upvotes: 0
Views: 773
Reputation: 6168
I would recommend against parsing CSV manually, you'll most likely eventually encounter one of the annoying edge cases (values with lines or columns separators, for instance). It's often better and safer to use dedicated libraries.
I'm going to recommend kantan.csv because I'm the author, but there are plenty other quality libraries out there (product-collections, pure csv...).
With kantan.csv, your problem would be solved thusly:
import kantan.csv.ops._
// For an immutable structure.
new java.io.File("test.csv").readCsv[List, List[Double]](',', false)
// For an Array, as in your example.
new java.io.File("test.csv").readCsv[Array, Array[Double]](',', false)
Upvotes: 0
Reputation: 8663
toDouble
is right, just call it on strings.
rows.map(_.map(_.toDouble))
Or right in your code
using(io.Source.fromFile("test.csv")) { source =>
for (line <- source.getLines) {
rows += line.split(",").map(_.trim).map(_.toDouble)
}
}
To avoid mutable collections you could use lists, like this:
val rows: List[List[Double]] = using(io.Source.fromFile("test.csv")) { source =>
source.getLines.toList map { line =>
line.split(",").map(_.trim.toDouble).toList
}
}
Upvotes: 3