0

I'm new to Scala and am having trouble iterating through an array to assign values to a Matrix. My programming background is mostly Python, so I'm having difficulty seeing the functional way to do this task.

I've got an Array, val averages = Array(1,2,3,4,5,6,7,8,9), and I've got an empty 3x3 matrix, M, made with Scala library breeze. I need to take the values from the Array and put them into the matrix.

Normally, I would try something like:

 var index = 0
 for(i <- 0 until M.cols)
        for(j <- 0 until M.rows)
            M(i,j) = averages(index)
            index += 1

This doesn't work, and results in a matrix simply filled with "1"s. I assume this is because Scala is evaluating M(i,j) = averages(index) before it gets to index += 1. I've experimented with different types of for loops for averages, but can't quite get the result I want:

1 2 3
4 5 6
7 8 9 

I know that in Scala with the Random collection you can do this, and fill the matrix with random variables:

 val r = new scala.util.Random(0)
 for(i <- 0 until M.rows)
    for(j <- 0 until M.cols)
        M(i, j) = r.nextDouble() 

But looking at the Scala documentation, Array doesn't have the .next method.

At any rate, even using .next is very iterative, and not a functional solution. Can anyone help me 1) Figure out the proper way to loop through averages and/or 2) Figure out a functional way to do this? Thanks!

3
  • 1
    val averages = Array(1,2,3,4,5,6,7,8,9).toIterator Now it has a next. Commented Jan 10, 2017 at 20:47
  • 2
    You just need braces (to make a block) around both statements you want executed in your first for-loop. Scala uses {}, not indentation like Python, for scoping Commented Jan 10, 2017 at 20:54
  • You should check library's Scaladoc also, probably there is already a method that you need, like Matrix.create(3, 3, array)... Commented Jan 10, 2017 at 21:05

2 Answers 2

2

Are you sure you're not just having a brackets issue? The code you provided above looks like it ought to be:

 var index = 0
 for(i <- 0 until M.cols)
    for(j <- 0 until M.rows) {
        M(i,j) = averages(index)
        index += 1
    }

If you don't include those braces, only the first line of the second for loop will run. Java/Scala rely on these braces to group things. You can't rely on indenting like Python. If you don't want to use the index parameter, some math works too:

for(i <- 0 until M.cols
    for(j <- 0 until M.rows) {
        M(i, j) = 1 + i + j * M.cols
Sign up to request clarification or add additional context in comments.

Comments

2

Copying data from one existing collection to another is, by definition, relying on side effects to accomplish your goals. A more FP approach is to build a new one directly from the old.

I don't have Breeze installed but, according to the scaladocs, something like this should be possible.

Matrix((0 until colLen).map(x => averages.slice(x*rowLen, (x+1)*rowLen)))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.