从List [Any]转到特定案例类的简洁方法

时间:2018-10-08 02:01:57

标签: scala

我有一个List[Any],看起来像:

val a: List[Any] = List(1, "a", "b", 2.0)

我还有一个case class,看起来像:

case class Data(field1: Int, field2: String, field3: String, field4: Double)

我想使用case class中的值实例化一个a 数据,使其看起来像:

val d = Data(1, "a", "b", 2.0)

我知道我可以遍历a,但是对于一大堆似乎很麻烦的列表。

2 个答案:

答案 0 :(得分:6)

如果您使用的是无形状,

libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.3"

您可以将元组应用于案例类,

scala> import shapeless._
import shapeless._

scala> import syntax.std.traversable._
import syntax.std.traversable._

scala> case class Data(field1: Int, field2: String, field3: String, field4: Double)
defined class Data

scala> val a: List[Any] = List(1, "a", "b", 2.0)
a: List[Any] = List(1, a, b, 2.0)

scala> (Data.apply _) tupled a.toHList[Int::String::String::Double::HNil].get.tupled
res1: Data = Data(1,a,b,2.0)

在数据类上应用元组的类型安全方式

scala> a.toHList[Int::String::String::Double::HNil].map(_.tupled).map(t => (Data.apply _) tupled t)
res2: Option[Data] = Some(Data(1,a,b,2.0))

答案 1 :(得分:3)

无法以类型安全的方式执行此操作。直到运行时才知道列表的长度,因此无法确保a.length == Data#productArity(请参阅?我们正在将实例的字段与类型的字段进行比较)。 / p>

首先应该考虑如何不使用List来表示数据。

如果您可以将数据表示为元组,则可以使用this answer作为灵感,但是这里有一条龙:元组几乎与此处的列表一样可疑。尝试直接实例化您的case class