2011-11-10 9 views
43

ケースクラスをタプルに変換する簡単な方法はありますか?Scalaでは、ケースクラスをタプルに変換する簡単な方法はありますか?

私は、もちろん、これを行う定型コードを簡単に書くことができますが、定型文なしでは意味があります。

私が本当に後にしているのは、簡単にケースクラスを辞書順に並べ替える方法です。 scala.math.Ordering.Implicits._をインポートしてタプルの目標を達成できます。私のタプルにはOrderingが定義されています。しかし、scala.math.Orderingの暗黙は、一般的なケースクラスでは機能しません。

答えて

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のヒントのおかげで、私は()を "取り除く"ことができました – Tanjona

+0

非常に涼しい!私は適用されないことについて全く知らなかった –

+0

クール、それは働いた!あなたの提案で私は私のケースクラスを得ることができました。次のようにしてオーダーしました: 'val thisTuple:Ordered [(String、Int)] = Foo.unapply(this).get; val thatTuple = Foo.unapply(それ).get; thisTupleはthatTuple'を比較します。 これは世界で最も美しいものではありませんので、私はまだ提案はしていますが、あなたの答えは確かに仕事を完了させます。ありがとう! – Douglas

3

あなたはN = 1-22、TupleNが伸びるため、ProductN形質を拡張してみてください可能性があります。 _1_2などのような、多くのタプルセマンティクスを提供します。タイプの使い方によっては、実際のタプルを作成しなくても十分です。

+0

私はこのアプローチをどのように働かせるかわかりません。私は、私のケースクラスを辞書順に並べ替えたり、定型文をたくさん書かなくても辞書編集の順序付けをしたいと思っています。 ProductNの拡張は、scala.math.Orderingのimplicitsで動作していないように見えます。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) 

パフォーマンスホーリーになる可能性が高いあなたが絶えず変換しているからです。おそらく、すべてを変換したフォームに変換し、並べ替えてから、(Fnord.apply _).tupledのようなものを使って元に戻してください。

関連する問題