В Scala, как я могу превратить кучу CSV-файлов в массив массивов - PullRequest
2 голосов
/ 20 августа 2011

Я хочу преобразовать все файлы в 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 ]

8 голосов
/ 20 августа 2011

Делая это:

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))
3 голосов
/ 20 августа 2011

Ответ Бена хороший (я проголосовал за него), но можно пойти немного дальше с простотой понимания - и сделать код более читабельным и самодокументируемым в процессе.

Хитрость заключается в том, чтобыиспользуйте = в понимании, а также <-.Хорошая особенность, которую не так часто можно встретить в дикой природе:

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 голосов
/ 20 августа 2011

Если вам это нужно для производства (то есть вы должны обрабатывать настоящие CSV-файлы, которые могут быть более сложными, чем предполагает название, например, с кавычками и т. Д.), Используйте Apache Общая библиотека CSV . Это на Java, но, эй, если бы нам не нужна была совместимость с Java, мы бы все использовали Haskell, амирит?

1 голос
/ 21 августа 2011

Или используйте однострочник:

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))

Не то, чтобы я рекомендовал однострочники.Просто в качестве альтернативы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...