B3th4 - 8 months ago 53

Scala Question

`def produced(sol:Array[Int]):Array[Array[Int]]={`

println("hello")

val buf = scala.collection.mutable.ArrayBuffer.empty[Array[Int]]

var productAtTime = Array.fill[Int](NumItem)(0)

var z=0

while(z<NumPeriod){

var x =sol(z)

if(x != -1){

productAtTime(x)=productAtTime(x)+1

println(productAtTime.mkString)

buf+=productAtTime

var arraybuf= buf.toArray

println(arraybuf.deep.mkString)

}

else{

buf+=productAtTime

}

z+=1

}

return buf.toArray

}

I'm trying to create an Array using an ArrayBuffer. Each element of this ArrayBuffer is an array. Each element should be the same as the previous one, except for at most one element that should be incremented by one. (no incrementation if sol(z)=-1, else there is one)

So for each z from 0 to NumPeriod I create an Array based on the previous one, and I would like to append this array to my buffer. For some reason, the array that is appended also replaces all the previous arrays in the buffer by itself.

ex. output of the prints I get: for sol= (1,1,-1,0,0)

`hello`

01

Array(0, 1)

02

Array(0, 2)Array(0, 2)

12

Array(1, 2)Array(1, 2)Array(1, 2)Array(1, 2)

22

Array(2, 2)Array(2, 2)Array(2, 2)Array(2, 2)Array(2, 2)

As can be seen, the array that has to be appended exist but during the += it also changes all the previous arrays that are in the ArrayBuffer.

I would like something like:

`hello`

01

Array(0, 1)

02

Array(0, 1)Array(0, 2)

12

Array(0, 1)Array(0, 2)Array(0, 2)Array(1, 2)

22

Array(0, 1)Array(0, 2)Array(0, 2)Array(1, 2)Array(2, 2)

Answer Source

You're referencing (pointing to) the same `Array[Int]`

each time inside your `Array[Array[Int]]`

, that's why you're seeing the same values repeated. You need to allocate a *new array* on each iteration. You can do this via `Array[T].clone`

:

```
$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_91).
Type in expressions for evaluation. Or try :help.
scala> :pa
// Entering paste mode (ctrl-D to finish)
def produced(sol: Array[Int]): Array[Array[Int]] = {
val NumItem = 2
val NumPeriod = 5
println("hello")
val buf = scala.collection.mutable.ArrayBuffer.empty[Array[Int]]
var productAtTime: Array[Int] = Array.fill[Int](NumItem)(0)
var z = 0
while (z < NumPeriod) {
val x = sol(z)
if (x != -1) {
productAtTime(x) = productAtTime(x) + 1
println(productAtTime.mkString)
buf += productAtTime.clone()
val arraybuf = buf.toArray
println(arraybuf.deep.mkString)
}
else {
buf += productAtTime.clone()
}
z += 1
}
buf.toArray
}
// Exiting paste mode, now interpreting.
produced: (sol: Array[Int])Array[Array[Int]]
scala> produced(Array(1, 1, -1, 0, 0))
hello
01
Array(0, 1)
02
Array(0, 1)Array(0, 2)
12
Array(0, 1)Array(0, 2)Array(0, 2)Array(1, 2)
22
Array(0, 1)Array(0, 2)Array(0, 2)Array(1, 2)Array(2, 2)
res1: Array[Array[Int]] = Array(Array(0, 1), Array(0, 2), Array(0, 2), Array(1, 2), Array(2, 2))
```