In Scala, is there an easy way to convert a case class into a tuple?

匆匆过客 提交于 2019-11-26 22:36:18

问题


Is there an easy way to convert a case class into a tuple?

I can, of course, easily write boilerplate code to do this, but I mean without the boilerplate.

What I'm really after is a way to easily make a case class lexicographically Ordered. I can achieve the goal for tuples by importing scala.math.Ordering.Implicits._, and voila, my tuples have an Ordering defined for them. But the implicits in scala.math.Ordering don't work for case classes in general.


回答1:


How about calling unapply().get in the companion object?

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

val (str, in) = Foo.unapply(Foo("test", 123)).get
// str: String = test
// in: Int = 123



回答2:


Shapeless will do this for you.

  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)

Gets

res0: List[Fnord] = List(Fnord(1,a - first), Fnord(1,z - last))

productElements turns a case class into a Shapeless HList:

scala> Fnord(1, "z - last").productElements
res1: Int :: String :: shapeless.HNil = 1 :: z - last :: HNil

And HLists are converted to tuples with #tupled:

scala> Fnord(1, "z - last").productElements.tupled
res2: (Int, String) = (1,z - last)

Performance is likely to be horrible, since you're constantly converting. You'd probably convert everything to the tupled form, sort that, then convert it back using something like (Fnord.apply _).tupled.




回答3:


You might try extending the ProductN trait, for N=1-22, which TupleN extends. It will give you a lot of Tuple semantics, like the _1, _2, etc. methods. Depending on you how you use your types, this might be sufficient without creating an actual Tuple.




回答4:


Came across this old thread while attempting to do this same thing. I eventually settled on this solution:

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

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

val (str, in) = testFoo match { case Foo(f, b) => (f, b) }


来源:https://stackoverflow.com/questions/8087958/in-scala-is-there-an-easy-way-to-convert-a-case-class-into-a-tuple

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!