Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I don't know if this is the easy way, but I've included some code below for converting nested tuples into '2D' arrays.</p> <p>First, you need some boiler plate for getting the size of the tuples as well as converting the tuples into <code>[Array[Array[Double]]</code>. The series of steps I used were:</p> <ol> <li>Figure out the number of rows and columns in the tuple</li> <li>Turn the nested tuple into a one row Array</li> <li>Reshape the array based on the size of the original tuple.</li> </ol> <p>The code for that is:</p> <pre><code>object Matrix { /** * Returns the size of a series of nested tuples. */ def productSize(t: Product): (Int, Int) = { val a = t.productArity val one = t.productElement(0) if (one.isInstanceOf[Product]) { val b = one.asInstanceOf[Product].productArity (a, b) } else { (1, a) } } /** * Flattens out a nested tuple and returns the contents as an iterator. */ def flattenProduct(t: Product): Iterator[Any] = t.productIterator.flatMap { case p: Product =&gt; flattenProduct(p) case x =&gt; Iterator(x) } /** * Convert a nested tuple to a flattened row-oriented array. * Usage is: * {{{ * val t = ((1, 2, 3), (4, 5, 6)) * val a = Matrix.toArray(t) * // a: Array[Double] = Array(1, 2, 3, 4, 5, 6) * }}} * * @param t The tuple to convert to an array */ def toArray(t: Product): Array[Double] = flattenProduct(t).map(v =&gt; v match { case c: Char =&gt; c.toDouble case b: Byte =&gt; b.toDouble case sh: Short =&gt; sh.toDouble case i: Int =&gt; i.toDouble case l: Long =&gt; l.toDouble case f: Float =&gt; f.toDouble case d: Double =&gt; d case s: String =&gt; s.toDouble case _ =&gt; Double.NaN } ).toArray[Double] def rowArrayTo2DArray[@specialized(Int, Long, Float, Double) A: Numeric](m: Int, n: Int, rowArray: Array[A]) = { require(rowArray.size == m * n) val numeric = implicitly[Numeric[A]] val newArray = Array.ofDim[Double](m, n) for (i &lt;- 0 until m; j &lt;- 0 until n) { val idx = i * n + j newArray(i)(j) = numeric.toDouble(rowArray(idx)) } newArray } /** * Factory method for turning tuples into 2D arrays */ def apply(data: Product): Array[Array[Double]] = { def size = productSize(data) def array = toArray(data) rowArrayTo2DArray(size._1, size._2, array) } } </code></pre> <p>Now to use this, you could just do the following:</p> <pre><code>val a = Matrix((1, 2, 3)) // a: Array[Array[Double]] = Array(Array(1.0, 2.0, 3.0)) val b = Matrix(((1, 2, 3), (4, 5, 6), (7, 8, 9))) // b: Array[Array[Double]] = Array(Array(1.0, 2.0, 3.0), // Array(4.0, 5.0, 6.0), // Array(7.0, 8.0, 9.0)) val c = Matrix((1L, 2F, "3")) // Correctly handles mixed types // c: Array[Array[Double]] = Array(Array(1.0, 2.0, 3.0)) val d = Matrix((1L, 2F, new java.util.Date())) // Non-numeric types convert to NaN // d: Array[Array[Double]] = Array(Array(1.0, 2.0, NaN)) </code></pre> <p>Alternatively, if you could just call the rowArrayTo2DArray directly using the size of the array you want and a 1D array of values:</p> <pre><code>val e = Matrix.rowArrayTo2DArray(1, 3, Array(1, 2, 3)) // e: Array[Array[Double]] = Array(Array(1.0, 2.0, 3.0)) val f = Matrix.rowArrayTo2DArray(3, 1, Array(1, 2, 3)) // f: Array[Array[Double]] = Array(Array(1.0), Array(2.0), Array(3.0)) val g = Matrix.rowArrayTo2DArray(3, 3, Array(1, 2, 3, 4, 5, 6, 7, 8, 9)) // g: Array[Array[Double]] = Array(Array(1.0, 2.0, 3.0), // Array(4.0, 5.0, 6.0), // Array(7.0, 8.0, 9.0)) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

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