我们有许多Scala类返回Map [String,String](键,值)结果,以便存储在NoSQL数据库中。一些结果实际上是Map [String,List]或Map [String,ArrayBuffer],所以我们在那些对象上使用.toString进行转换。这为我们提供了如下输出:
"ArrayBuffer(1,2,3,4)"
或
"List(1,2,4)"
我们不希望包含对象类型,而是根据需要将这些内容写成直接的CSV,引号和转义字符。有一个很好的CSV库可以很好地与Scala一起使用吗?
答案 0 :(得分:1)
Here's一个类似的问题,应该涵盖CSV部分。我查看了有关csv的Scala问题,似乎没有任何关于创建 csv的东西的建议,而不仅仅是解析它。所以我会研究Java库。
答案 1 :(得分:0)
如果您只想序列化单个列表或数组而不正确转义引号等:
scala> List(1,2,3,4).mkString(",")
res39: String = 1,2,3,4
如果您希望序列化稍微复杂的数据结构: product-collections将序列化元组或案例类(任何产品)的集合到csv并正确地转义引号。
scala> List ((1,"Jan"),
| (2,"Feb"),
| (3,"Mar","Extra column")).csvIterator.mkString("\n")
res41: String =
1,"Jan"
2,"Feb"
3,"Mar","Extra column"
产品系列也会直接写入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"""
答案 2 :(得分:0)
如果您还想要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中可能会变得棘手,您可以为此部分选择不同的包装。