Note that there are some explanatory texts on larger screens.

plurals
  1. POInstantiating a case class from a list of parameters
    text
    copied!<p>Given:</p> <pre><code>case class Foo(a: Int, b: String, c: Double) </code></pre> <p>you can say:</p> <pre><code>val params = Foo(1, "bar", 3.14).productIterator.toList </code></pre> <p>and get:</p> <pre><code>params: List[Any] = List(1, bar, 3.14) </code></pre> <p>Is there a way to "go backwards" and recreate a Foo object directly from this list, i.e.:</p> <pre><code>Foo.createFromList(params) // hypothetical </code></pre> <p>instead of writing:</p> <pre><code>Foo(params(0).asInstanceOf[Int], params(1).asInstanceOf[String], params(2).asInstanceOf[Double]) </code></pre> <p>EDIT: it seems that it boils down to being able to send the elements of a list as parameters to a function without writing them out explicitly, e.g.:</p> <pre><code>def bar(a: Int, b: Int, c: Int) = //... val list = List(1, 2, 3, 4, 5) bar(list.take(3)) // hypothetical, instead of: bar(list(0), list(1), list(2)) </code></pre> <p>I would sort of expect to be able to do:</p> <pre><code>bar(list.take(3): _*) </code></pre> <p>but that doesn't seem to work.</p> <p>EDIT: Solution based on extempore's answer, but invoking the constructor directly instead of using the apply method:</p> <pre><code>case class Foo(a: Int = 0, b: String = "bar", c: Double = 3.14) { val cs = this.getClass.getConstructors def createFromList(params: List[Any]) = cs(0).newInstance(params map { _.asInstanceOf[AnyRef] } : _*).asInstanceOf[Foo] } </code></pre> <p>Now you can do:</p> <pre><code>scala&gt; Foo().createFromList(List(4, "foo", 9.81)) res13: Foo = Foo(4,foo,9.81) </code></pre> <p>You can also refactor the creation method into a trait:</p> <pre><code>trait Creatable[T &lt;: Creatable[T]] { val cs = this.getClass.getConstructors def createFromList(params: List[Any]) = cs(0).newInstance(params map { _.asInstanceOf[AnyRef] } : _*).asInstanceOf[T] } case class Bar(a: Int = 0, b: String = "bar", c: Double = 3.14) extends Creatable[Bar] </code></pre> <p>And do e.g.:</p> <pre><code>scala&gt; val bar = Bar() bar: Bar = Bar(0,bar,3.14) scala&gt; bar == bar.createFromList(bar.productIterator.toList) res11: Boolean = true </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload