59

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

もちろん、これを行うための定型文を簡単に書くことはできますが、定型文がないことを意味します。

私が本当に求めているのは、ケースクラスを辞書式順序で簡単に作成する方法です。scala.math.Ordering.Implicits._をインポートすることでタプルの目標を達成できます。そして、出来上がりです。タプルには順序が定義されています。しかし、scala.math.Orderingの暗黙の要素は、一般にケースクラスでは機能しません。

4

5 に答える 5

88

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

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

val (str, in) = Foo.unapply(Foo("test", 123)).get
// str: String = test
// in: Int = 123
于 2011-11-11T00:08:03.000 に答える
6

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

また、HListは#tupledを使用してタプルに変換されます。

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

常に変換しているため、パフォーマンスはひどいものになる可能性があります。おそらく、すべてを3倍の形式に変換し、それを並べ替えてから、のようなものを使用して元に戻し(Fnord.apply _).tupledます。

于 2018-02-05T20:03:23.237 に答える
3

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

于 2011-11-11T17:42:38.460 に答える
3

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

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

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

val (str, in) = testFoo match { case Foo(f, b) => (f, b) }
于 2017-04-09T18:00:14.633 に答える
3

Scala 3は、ケースクラスとタプル間の変換をファーストクラスでサポートしています。

scala> case class Foo(foo: String, bar: Int)
// defined case class Foo

scala> Tuple.fromProductTyped(Foo("a string", 1))
val res0: (String, Int) = (a string,1)

scala> summon[deriving.Mirror.ProductOf[Foo]].fromProduct(res0)
val res1: deriving.Mirror.ProductOf[Foo]#MirroredMonoType = Foo(a string,1)
于 2021-09-16T12:36:47.337 に答える