在Scala中,如何将一堆CSV文件转换为数组数组

时间:2011-08-20 09:41:26

标签: scala

我希望将所有文件转换为Array[Array[String]]。第一个维度应该是行号。第二个维度应该是列号。到目前为止我已经

  for (file <- allFiles) {

    val split = for (line <- Source.fromFile(...) yield line.split(",")

  } yield split

但它似乎没有起作用。作为一个具体的例子,如果我有

file1.csv

a,b,c
d,e,f

file2.csv

1,2,3

我想要输出

a,b,c
d,e,f
1,2,3

4 个答案:

答案 0 :(得分:8)

通过这样做:

for (line <- Source.fromFile(...)) ...

您正在迭代文件中的每个字符,而不是每行。

你可能意味着:

for (line <- Source.fromFile(...).getLines) ...

顺便说一句,您可以将两个for理解合并为一个:

scala> val allFiles = Array("data1.csv", "data2.csv")
allFiles: Array[java.lang.String] = Array(data1.csv, data2.csv)

scala> for {
     |   filename <- allFiles
     |   line <- io.Source.fromFile(filename).getLines
     | } yield line.split(",")
res3: Array[Array[java.lang.String]] = Array(Array(a, b, c), Array(d, e, f), Array(1, 2, 3))

答案 1 :(得分:3)

Ben的答案很好(我赞成它),但是可以进一步了解for-comprehensions - 并使代码在此过程中更具可读性和自我记录。

诀窍是在理解中使用=,以及<-。一个很好的功能,在野外几乎不常见:

val allFiles = Array("data1.csv", "data2.csv")
val parsedLines = for {
  filename <- allFiles
  file = io.Source fromFile filename
  line <- file.getLines
  entries = line split ","
} yield entries

答案 2 :(得分:2)

如果您需要生产(也就是说,您必须处理真实的CSV文件,这可能比名称所暗示的更复杂,带引号和所有文件),请使用Apache的{ {3}}库。这是Java,但是,如果我们不需要Java兼容性,我们都会使用Haskell,amirite?

答案 3 :(得分:1)

或使用单行:

val aa = List ("abc.csv", "123.csv").map (io.Source.fromFile (_).getLines .map (_.split (","))).flatten.toArray
aa: Array[Array[java.lang.String]] = Array(Array(a, b, c), Array(d, e, f), Array(1, 2, 3))

不是我会推荐单行。作为替代方案。