有没有一种简单的方法可以将案例类转换为元组?
当然,我可以很容易地编写样板代码来做到这一点,但我的意思是没有样板代码。
我真正追求的是一种轻松使案例类按字典顺序排列的方法。我可以通过导入 scala.math.Ordering.Implicits._ 来实现元组的目标,瞧,我的元组为它们定义了一个排序。但是 scala.math.Ordering 中的隐含通常不适用于案例类。
有没有一种简单的方法可以将案例类转换为元组?
当然,我可以很容易地编写样板代码来做到这一点,但我的意思是没有样板代码。
我真正追求的是一种轻松使案例类按字典顺序排列的方法。我可以通过导入 scala.math.Ordering.Implicits._ 来实现元组的目标,瞧,我的元组为它们定义了一个排序。但是 scala.math.Ordering 中的隐含通常不适用于案例类。
调用unapply().get
伴生对象怎么样?
case class Foo(foo: String, bar: Int)
val (str, in) = Foo.unapply(Foo("test", 123)).get
// str: String = test
// in: Int = 123
Shapeless会为您做到这一点。
import shapeless._
import shapeless.syntax.std.product._
case class Fnord(a: Int, b: String)
List(Fnord(1, "z - last"), Fnord(1, "a - first")).sortBy(_.productElements.tupled)
获取
res0: List[Fnord] = List(Fnord(1,a - first), Fnord(1,z - last))
productElements 将 case 类转换为 Shapeless HList:
scala> Fnord(1, "z - last").productElements
res1: Int :: String :: shapeless.HNil = 1 :: z - last :: HNil
并且 HLists 使用#tupled 转换为元组:
scala> Fnord(1, "z - last").productElements.tupled
res2: (Int, String) = (1,z - last)
性能可能会很糟糕,因为您一直在转换。您可能会将所有内容转换为元组形式,对其进行排序,然后使用类似(Fnord.apply _).tupled
.
您可以尝试扩展ProductN
特征,对于 N=1-22,它会TupleN
扩展。它会给你很多元组语义,比如_1
,_2
等方法。根据您使用类型的方式,这可能就足够了,而无需创建实际的元组。
Scala 3 对案例类和元组之间的转换具有一流的支持:
scala> case class Foo(foo: String, bar: Int)
// defined case class Foo
scala> Tuple.fromProductTyped(Foo("a string", 1))
val res0: (String, Int) = (a string,1)
scala> summon[deriving.Mirror.ProductOf[Foo]].fromProduct(res0)
val res1: deriving.Mirror.ProductOf[Foo]#MirroredMonoType = Foo(a string,1)
在尝试做同样的事情时遇到了这个旧线程。我最终确定了这个解决方案:
case class Foo(foo: String, bar: Int)
val testFoo = Foo("a string", 1)
val (str, in) = testFoo match { case Foo(f, b) => (f, b) }