2011-11-10 29 views
43

Bir vaka sınıfını bir tuple dönüştürmenin kolay bir yolu var mı?Scala'da, bir vaka sınıfını bir tuple dönüştürmenin kolay bir yolu var mı?

Elbette, bunu yapmak için boilerplate kodunu kolayca yazabilirim, ama boilerplate olmadan demek istiyorum.

Gerçekten peşindeyim, sözdizimsel olarak bir vaka sınıfını kolayca hazırlamanın bir yoludur. Scala.math.Ordering.Implicits._ ve voila'yı içe aktararak tuplelar için bir hedefe ulaşabilirim. Ama scala.math.Ordering içindeki imalar genel olarak vaka sınıfları için çalışmıyor.

cevap

64

Companion nesnesinde unapply().get() aranması nasıl olur? Eğer N = 1-22, TupleN uzanır için ProductN özelliği, uzanan çalışabilir

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

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

İpuçlarınız için teşekkürler, REPL 2.9.0-1 'de "almak" için – Tanjona

+0

çok serin! Unutply –

+0

Cool hakkında hiçbir fikrim yoktu, işe yaradı! Senin öneri ile ben benim dava sınıfını elde edebildi emredilmiş gibi: 'val thisTuple: Sipariş [(String, Int)] = Foo.unapply (this) .get; val thatTuple = Foo.unapply (bu) .get; BuTuple, onu karşılaştırır. Dünyadaki en güzel şey bu değil, bu yüzden hala önerilere açığım, ama cevabınız kesinlikle işi bitiriyor. Teşekkürler! – Douglas

3

. Size _1, _2, vb. Gibi bir çok Tuple semantiği verecektir. Tiplerini nasıl kullandığınıza bağlı olarak, bu gerçek bir Tuple oluşturmadan yeterli olabilir.

+0

Bu yaklaşımı benim için nasıl çalıştıracağımı bilmiyorum. Dava sınıfımın alfabetik olarak sıralanması ya da bir çok alfabeye gerek kalmadan sözlükbilgisel bir Siparişe sahip olmasını istiyorum. ProductN'u genişletmek, scala.math.Condering içindeki implicits ile çalışmak gibi görünmüyor. – Douglas

0

Aynı şeyi yapmaya çalışırken bu eski iş parçacığına rastladım. Sonunda bu çözüm üzerinde yerleşmiş:

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 sizin için yapacaktır.

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 bir Biçimsizler hList içine bir vaka sınıfını döner alır:

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

Ve HLists #tupled ile küpe dönüştürülür:

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

Performans horri olması muhtemeldir Sürekli dönüşüm yaptığınız için. Muhtemelen her şeyi tupled formuna dönüştürürsünüz, sıralayın, sonra (Fnord.apply _).tupled gibi bir şeyi kullanarak geri dönüştürün.

İlgili konular