59

有没有一种简单的方法可以将案例类转换为元组?

当然,我可以很容易地编写样板代码来做到这一点,但我的意思是没有样板代码。

我真正追求的是一种轻松使案例类按字典顺序排列的方法。我可以通过导入 scala.math.Ordering.Implicits._ 来实现元组的目标,瞧,我的元组为它们定义了一个排序。但是 scala.math.Ordering 中的隐含通常不适用于案例类。

4

5 回答 5

88

调用unapply().get伴生对象怎么样?

case class Foo(foo: String, bar: Int)

val (str, in) = Foo.unapply(Foo("test", 123)).get
// str: String = test
// in: Int = 123
于 2011-11-11T00:08:03.000 回答
6

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.

于 2018-02-05T20:03:23.237 回答
3

您可以尝试扩展ProductN特征,对于 N=1-22,它会TupleN扩展。它会给你很多元组语义,比如_1,_2等方法。根据您使用类型的方式,这可能就足够了,而无需创建实际的元组。

于 2011-11-11T17:42:38.460 回答
3

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)
于 2021-09-16T12:36:47.337 回答
3

在尝试做同样的事情时遇到了这个旧线程。我最终确定了这个解决方案:

case class Foo(foo: String, bar: Int)

val testFoo = Foo("a string", 1)

val (str, in) = testFoo match { case Foo(f, b) => (f, b) }
于 2017-04-09T18:00:14.633 回答