简体   繁体   中英

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

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.

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

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 .

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.

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) }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM