elm
elm

Reputation: 20415

Scala case class arguments instantiation from array

Consider a case class with a possibly large number of members; to illustrate the case assume two arguments, as in

case class C(s1: String, s2: String)

and therefore assume an array with size of at least that many arguments,

val a = Array("a1", "a2")

Then

scala> C(a(0), a(1))
res9: C = c(a1,a2)

However, is there an approach to case class instantiation where there is no need to refer to each element in the array for any (possibly large) number of predefined class members ?

Upvotes: 5

Views: 7383

Answers (3)

elm
elm

Reputation: 20415

Having gathered bits and pieces from the other answers, a solution that uses Shapeless 2.0.0 is thus as follows,

import shapeless._
import HList._
import syntax.std.traversable._

val a = List("a1", 2)                    // List[Any]
val aa = a.toHList[String::Int::HNil]
val aaa = aa.get.tupled                  // (String, Int)

Then we can instantiate a given case class with

case class C(val s1: String, val i2: Int)
val ins = C.tupled(aaa)

and so

scala> ins.s1
res10: String = a1

scala> ins.i2
res11: Int = 2

The type signature of toHList is known at compile time as much as the case class members types to be instantiate onto.

Upvotes: 4

Mark Lister
Mark Lister

Reputation: 1143

To convert a Seq to a tuple see this answer: https://stackoverflow.com/a/14727987/2483228

Once you have a tuple serejja's answer will get you to a c.

Note that convention would have us spell c with a capital C.

Upvotes: 3

serejja
serejja

Reputation: 23881

No, you can't. You cannot guarantee your array size is at least the number of members of your case class.

You can use tuples though.

Suppose you have a mentioned case class and a tuple that looks like this:

val t = ("a1", "a2")

Then you can do:

c.tupled(t)

Upvotes: 7

Related Questions