I've asked this question on https://users.scala-lang.org/ but haven't got a concrete answer yet. I am given a vector v
and I would like to construct a matrix m
based on this vector according to the rules specified below. I would like to write the following code in a purely functional way, i.e. m = v.map(...)
or similar. I can do it easily in procedural way like this
import scala.util.Random
val v = Vector.fill(50)(Random.nextInt(100))
println(v)
val m = Array.fill[Int](10, 10)(0)
def populateMatrix(x: Int): Unit = m(x/10)(x) = 1
v.map(x => populateMatrix(x))
m foreach { row => row foreach print; println }
In words, I am iterating through v
, getting a pair of indices (i,j)
from each v(k)
and updating the matrix m
at these positions, i.e., m(i)(j) = 1
. But I am seeking a functional way. It is clear for me how to implement this in, e.g. Mathematica
v=RandomInteger[{99}, 300]
m=SparseArray[{Rule[{Quotient[#, 10] 1, Mod[#, 10] 1}, 1]}, {10, 10}] & /@ v // Total // Normal
But how to do it in scala, which is functional language, too?
CodePudding user response:
Your populate matrix approach can be "reversed" - map vector into index tuples, group them, count size of each group and turn it into map (index tuple -> size) which will be used to populate corresponding index in array with Array.tabulate
:
val v = Vector.fill(50)(Random.nextInt(100))
val values = v.map(i => (i/10, i))
.groupBy(identity)
.view
.mapValues(_.size)
val result = Array.tabulate(10,10)( (i, j)=> values.getOrElse((i,j), 0))