web-dev-qa-db-ja.com

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

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

もちろん、これを行うためのボイラープレートコードを簡単に作成できますが、ボイラープレートがなくてもかまいません。

私が実際に求めているのは、ケースクラスを辞書式順序で簡単に作成する方法です。 scala.math.Ordering.Implicits._とvoilaをインポートすることでタプルの目標を達成でき、タプルにはOrderingが定義されています。しかし、scala.math.Orderingのインプリシットは、ケースクラスでは一般的に機能しません。

56
Douglas

コンパニオンオブジェクトでunapply().getを呼び出すのはどうですか?

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

val (str, in) = Foo.unapply(Foo("test", 123)).get
// str: String = test
// in: Int = 123
75
S-C

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は、ケースクラスをShapeless HListに変換します。

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

そしてHListは#tupledでタプルに変換されます:

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

常にコンバージョンを達成しているため、パフォーマンスは恐ろしいものになる可能性があります。おそらく、すべてをタプル形式に変換し、それを並べ替えてから、(Fnord.apply _).tupledのようなものを使用して変換します。

4
James Moore

ProductNが拡張するN = 1-22の場合、TupleN特性を拡張してみてください。 _1_2などのメソッドのような多くのタプルセマンティクスを提供します。タイプの使用方法によっては、実際のタプルを作成しなくても十分な場合があります。

3
Dean Wampler

同じことをやろうとしているときに、この古いスレッドに出くわしました。私は最終的にこの解決策に落ち着きました:

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

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

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