2011-11-10 76 views
43

有沒有簡單的方法將案例類轉換爲元組?在斯卡拉,是否有一種簡單的方法將案例類轉換爲元組?

我當然可以輕鬆地編寫樣板代碼來做到這一點,但我的意思是沒有樣板。

我真正追求的是一種輕鬆創建案例類按照字典順序排列的方法。我可以通過導入scala.math.Ordering.Implicits._實現元組的目標,並且瞧,我的元組爲它們定義了一個Ordering。但是,scala.math.Ordering中的含義對於一般的case類不起作用。

回答

64

如何在伴侶對象中調用unapply().get()

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

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

感謝您的提示,在REPL 2.9.0-1我不得不刪除()以「get」 – Tanjona

+0

非常酷!我不知道關於不適用 –

+0

酷,這工作!有了你的建議,我可以得到我的案例類有序如下:'val thisTuple:Ordered [(String,Int)] = Foo.unapply(this).get; val thatTuple = Foo.unapply(that).get;這個元組比較那個元組。 這不是世界上最漂亮的東西,所以我仍然樂於接受建議,但你的答案肯定會完成工作。謝謝! – Douglas

3

你可以嘗試延長ProductN性狀,N = 1-22,其中TupleN延伸。它會給你很多Tuple語義,如_1_2等方法。根據你如何使用你的類型,這可能就足夠了,而不需要創建一個實際的元組。

+0

我不確定如何讓這種方法爲我工作。我希望我的案例類或者按照字典順序排列或者有一個詞典排序順序,而不必編寫大量的樣板文件。擴展ProductN似乎不適用於scala.math.Ordering中的含義,它允許一個人輕鬆給元組賦予一個詞典順序。 – Douglas

0

在嘗試做同樣的事情時碰到了這個舊線程。我最終決定採用這個解決方案:

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會爲你做到這一點。

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接通的情況下,類成無形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) 

性能很可能是恐怖因爲你在不斷轉換。你可能會將所有東西都轉換成tupled形式,然後使用類似(Fnord.apply _).tupled的東西將其轉換回來。