Преобразование различных Seqs в CSV? - PullRequest
2 голосов
/ 04 октября 2010

У нас есть несколько классов Scala, возвращающих результаты Map [String, String] (ключ, значение) для хранения в базе данных NoSQL.Некоторые из результатов на самом деле являются Map [String, List] или Map [String, ArrayBuffer], поэтому мы используем .toString для этих объектов для преобразования.Это дает нам вывод, который выглядит следующим образом:

"ArrayBuffer(1,2,3,4)"

или

"List(1,2,4)"

Вместо того, чтобы включать тип объекта, мы хотели бы, чтобы они были записаны как прямые CSV, кавычки и экранированныесимволы по мере необходимости.Есть ли хорошая библиотека CSV, которая хорошо работает со Scala?

Ответы [ 3 ]

1 голос
/ 04 октября 2010

Вот аналогичный вопрос, который должен охватывать часть CSV. Я просмотрел вопросы Scala о csv, и, похоже, нет никаких предположений о том, что создаст csv, вместо того, чтобы просто анализировать его. Так что я бы заглянул в библиотеки Java.

0 голосов
/ 31 марта 2016

Вы можете сделать что-то вроде этого, если вам также нужны заголовки для файла CSV, и вы не возражаете против необходимости расширять черту с помощью собственной функции отображения строк. Эта черта здесь также включает в себя обратную часть загрузки вашего CSV обратно, также требуя вашей собственной функции отображения.

trait CsvSerialization[T] {

  import java.io.File
  import helpers.FileIO._

  def fileName: String
  def basePath: String
  def csvColumnHeaders: Array[String]
  def itemToRowMapper(item: T): List[String]
  def rowToItemMapper(row: Map[String, String]): T

  val filePath = basePath + File.separator + fileName

  def cached = new File(filePath).exists

  def toCsv(collection: Iterable[T]) = {
    println(basePath)
    makePathRecursive(basePath) // you can skip this in your code
    val writer = com.github.tototoshi.csv.CSVWriter.open(new File(filePath), append = false)      
    writer.writeRow(csvColumnHeaders.toList)   
    writer.writeAll(collection map  { collectionItem =>
      val csvRowSerialized = itemToRowMapper(collectionItem)
      require (
        csvRowSerialized.length == csvColumnHeaders.length,
        s"csv row mapping function returned ${csvRowSerialized.size} items whereas column headers has ${csvColumnHeaders.size} items")
      csvRowSerialized
    } toSeq)
    writer.close
  }

  def fromCsv: List[T] = {
    val reader = com.github.tototoshi.csv.CSVReader.open(new File(filePath))
    val collection = reader.allWithHeaders map { csvRow => 
      require (
        csvRow.size == csvColumnHeaders.length,
        s"csv row mapping function returned ${csvRow.size} items whereas column headers length has ${csvColumnHeaders.size} items")
      rowToItemMapper(csvRow)
    }
    reader.close
    collection
  }

}

Для этого кода необходимо включить базовую библиотеку CSV в ваш проект: https://github.com/tototoshi/scala-csv

Обратите внимание, что в Scala расширяющиеся черты могут становиться тернистыми, вы можете выбрать другую обертку для этой части.

0 голосов
/ 22 марта 2015

Если вы просто хотите сериализовать один список или массив без правильного экранирования кавычек и т. Д .:

scala> List(1,2,3,4).mkString(",")
res39: String = 1,2,3,4

Если вы хотите сериализовать немного более сложные структуры данных: product-collection будет сериализовать коллекцию кортежей или классов case (любой Product) в csv и корректно экранировать кавычки.

scala> List ((1,"Jan"),
     | (2,"Feb"),
     | (3,"Mar","Extra column")).csvIterator.mkString("\n")
res41: String =
1,"Jan"
2,"Feb"
3,"Mar","Extra column"

product-collection также будет записывать непосредственно в java.io.Writer. Он имеет коллекцию CollSeq, специализирующуюся на однородных кортежах, которые не позволяют использовать "дополнительный столбец" выше.

И для преобразования ваших исходных данных в формат, который может обрабатываться коллекциями продуктов:

scala> CollSeq(scala.collection.mutable.ArrayBuffer("a","b","quoted \"stuff\""):_*)
res52: com.github.marklister.collections.immutable.CollSeq1[String] =
CollSeq((a),
        (b),
        (quoted "stuff"))

scala> res52.csvIterator.mkString("\n")
res53: String =
"a"
"b"
"quoted ""stuff"""
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...