# Making array generation more functional

I have a problem of writing this code in a more functional fashion

``````import scala.util.Random

val v =  Vector.fill(5)(Random.nextInt(100))
println(v)

val m = Array.fill[Int](10, 10)(0)

def populateMatrix(x: Int): Unit = m(x/10)(x%10) += 1

v.map(x => populateMatrix(x))

m foreach { row => row foreach print; println }
``````

I would prefer something like

``````m=v.map(...)
``````

Have you tried using `ArraySeq.tabulate`?

@BalmungSan I do not see how it can be useful . If the length of `v` is `n` and the dimension of the matrix is `N` the complexity of my procedural approach is \$O(n)\$, whereas the complexity of `tabulate` would be \$O(N^2)\$.

`Array` is not in the functional realm to start with, so one cannot really expect an elaborate functional API on top of it. I also cannot imagine a reasonably generic method on `Vector` that might yield a nested `Array` of arbitrary size out of the box.

BTW, you are already tabulating - `#fill()` is implemented in terms of `#tabulate()`.

If you really want to keep on working with `Array`, implement the functionality you want for reuse, e.g.

``````def sparse[T : ClassTag](w: Int, h: Int)(inits: Vector[(Int, Int, T => T)]): Array[Array[T]] = {
val m = Array.ofDim[T](w, h)
inits.foreach { case (x, y, f) => m(x)(y) = f(m(x)(y)) }
m
}
val m = sparse[Int](10, 10)(v.map(i => (i / 10, i % 10, _ + 1)))
``````

â€¦and consider hiding it behind a thin wrapper type.

For linear algebra applications, you might alternatively look into libraries such as Breeze.

2 Likes

@sangamon I like your solution very much. But can you please explain what â€śhiding it behind a thin wrapper typeâ€ť explicitly mean.

Well, an `Array` is not a matrix. First, youâ€™ll want a place to put additional, matrix-specific methods that `Array` is lacking: addition, scalar multiplication,â€¦ A custom class wrapping an `Array` seems to be a good candidate for this. Of course you could just tack this functionality onto `Array` by means of implicit classes (or extension methods in Scala 3). Butâ€¦

â€¦then thereâ€™s additional constraints on matrices over arrays - the obvious first candidate being that you want matrices to be rectangular, whereas an `Array[Array[Int]]` can basically have any shape. (There may also be methods on `Array` that are inappropriate to invoke on a matrix.) And thatâ€™s, at the latest, where Iâ€™d start considering introducing a custom class wrapping the matrix `Array` (with a private constructor, so instances can only be created from methods on the wrapper class or factory methods on its companion object), e.g.

``````class Matrix[T : Numeric : ClassTag] private (private val arr: Array[Array[T]])
// ...
}
``````

The downside, of course, is that youâ€™ll have to explicitly expose any functionality you want to be available on matrices as custom methods, even if itâ€™s handily available on `Array` already. But Iâ€™d think the gains from the guarantees introduced by the custom type outweigh these nuisances in the long run.

That being said, I wouldnâ€™t venture into this specific area. If I needed matrix computations, Iâ€™d look for a linear algebra library. If this is about getting more familiar with Scala programming, Iâ€™d think thereâ€™s better domains that donâ€™t require fiddling with mutable arraysâ€¦

2 Likes