在Scala中将案例类转换为CSV

时间:2015-05-16 04:25:19

标签: scala csv macros case-class

是否有一种将案例类转换为CSV值的优雅方法。

例如 -

 case class Person( name : String, age : Int, gender: String, address : Option[String])

我在考虑使用宏,但想知道是否还有其他选择。

注意:案例类不包含任何用户定义的字段。

4 个答案:

答案 0 :(得分:10)

implicitsproductIterator怎么样?

implicit class CSVWrapper(val prod: Product) extends AnyVal {
    def toCSV() = prod.productIterator.map{
                    case Some(value) => value
                    case None => ""
                    case rest => rest
                  }.mkString(",")
}

Person("name", 30, "male", None).toCSV()

答案 1 :(得分:8)

是的,在Scala中有一种方法可以将案例类转换为CSV而不添加样板文件。例如PureCSV,基于令人惊叹的Shapeless库,可以做到:

scala> import purecsv.safe._
scala> case class Interval(start: Long, end: Long)
scala> Interval(10,20).toCSV()
res1: String = 1,10
scala> Seq(Interval(1,10),Interval(11,20)).toCSV("|")
res2: String =
1|10
11|20

注意:我是PureCSV的作者。

答案 2 :(得分:1)

product-collections也会为您生成csv。产品系列很好地扩展;它的反射自由&兼容scala-js。

import com.github.marklister.collections.io._
case class Foo(a:Int,b:String)
Seq(Foo(1,"hello"),Foo(2,"World")).csvIterator.mkString("\n")

res2: String =
1,"hello"
2,"World"

我是产品系列的作者

答案 3 :(得分:0)

要完成已接受的答案,您还可以将产品类型与模式匹配进行匹配:

implicit class CSVWrapper(val prod: Product) extends AnyVal {
  def toCSV: String = prod.productIterator.map{
    case p: Product =>  p.toCSV
    case rest => rest
  }.mkString(",")
}

这将适用于嵌入式案例类:

case class Address(street: String, town: String, country: Option[String])
case class Person( name : String, age : Int, gender: Option[String], address : Option[Address])

Person("myname", 30, Some("male"), Some(Address("mystreet", "city", None))).toCSV
// result :
// myname,30,male,mystreet,city,