2011-11-10 30 views
43

¿Existe alguna manera fácil de convertir una clase de caso en una tupla?En Scala, ¿hay alguna manera fácil de convertir una clase de caso en una tupla?

Puedo, por supuesto, escribir fácilmente el código repetitivo para hacer esto, pero me refiero sin la repetición.

Lo que realmente busco es una forma fácil de hacer una clase de casos ordenada lexicográficamente. Puedo lograr el objetivo de tuplas importando scala.math.Ordering.Implicits._ y voila, mis tuplas tienen un orden definido para ellos. Pero las implicaciones en Scala.math.Ordering no funcionan para las clases de casos en general.

Respuesta

64

¿Qué tal si llama al unapply().get() en el objeto complementario?

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

val (str, in) = Foo.unapply(Foo("test", 123)).get() 
+3

gracias por las sugerencias, en el REPL 2.9.0-1 tuve que quitar el() para "obtener" – Tanjona

+0

¡muy guay! No tenía idea acerca de la aplicación de –

+0

Cool, ¡funcionó! Con su sugerencia pude ordenar mi clase de caso así: 'val thisTuple: Ordenado [(String, Int)] = Foo.unaaplicación (this) .get; val thatTuple = Foo.unapply (that) .get; esteTuple compara eseTuple'. No es la cosa más bonita del mundo, por lo que todavía estoy abierto a sugerencias, pero su respuesta seguramente hace el trabajo. ¡Gracias! – Douglas

3

Usted puede tratar de extender el rasgo ProductN, para N = 1-22, que se extiende TupleN. Le dará mucha semántica Tuple, como los métodos _1, _2, etc. Dependiendo de cómo uses tus tipos, esto podría ser suficiente sin crear una Tupla real.

+0

No estoy seguro de cómo hacer que este enfoque funcione para mí. Quiero que mi clase de casos sea ordenada lexicográficamente o que tenga un pedido lexicográfico, sin tener que escribir muchos textos repetitivos. La ampliación de ProductN no parece funcionar con las implícitas en scala.math.Ordering que permiten fácilmente dar a las tuplas un orden lexicográfico. – Douglas

0

Encontré este viejo hilo mientras intentaba hacer lo mismo. Finalmente me decidí por esta solución:

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

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

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

Shapeless lo hará por ti.

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) 

Obtiene

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

productElements convierte una clase en un caso sin forma Hlist:

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

Y HLists se convierten en tuplas con #tupled:

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

Rendimiento es probable que sea horri ble, ya que estás convirtiendo constantemente. Probablemente convertirías todo a la forma agrupada, ordenaría eso y luego lo convertiría usando algo como (Fnord.apply _).tupled.

Cuestiones relacionadas