ケースクラスをタプルに変換する簡単な方法はありますか?
もちろん、これを行うための定型文を簡単に書くことはできますが、定型文がないことを意味します。
私が本当に求めているのは、ケースクラスを辞書式順序で簡単に作成する方法です。scala.math.Ordering.Implicits._をインポートすることでタプルの目標を達成できます。そして、出来上がりです。タプルには順序が定義されています。しかし、scala.math.Orderingの暗黙の要素は、一般にケースクラスでは機能しません。
ケースクラスをタプルに変換する簡単な方法はありますか?
もちろん、これを行うための定型文を簡単に書くことはできますが、定型文がないことを意味します。
私が本当に求めているのは、ケースクラスを辞書式順序で簡単に作成する方法です。scala.math.Ordering.Implicits._をインポートすることでタプルの目標を達成できます。そして、出来上がりです。タプルには順序が定義されています。しかし、scala.math.Orderingの暗黙の要素は、一般にケースクラスでは機能しません。
unapply().get
コンパニオンオブジェクトを呼び出すのはどうですか?
case class Foo(foo: String, bar: Int)
val (str, in) = Foo.unapply(Foo("test", 123)).get
// str: String = test
// in: Int = 123
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
ます。
ProductN
N = 1-22の場合、特性を拡張してみてくださいTupleN
。_1
、、_2
などのメソッドなど、多くのタプルセマンティクスが提供されます。タイプの使用方法によっては、実際のタプルを作成しなくてもこれで十分な場合があります。
これと同じことをしようとしているときに、この古いスレッドに出くわしました。私は最終的にこの解決策に落ち着きました:
case class Foo(foo: String, bar: Int)
val testFoo = Foo("a string", 1)
val (str, in) = testFoo match { case Foo(f, b) => (f, b) }
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)