Allen Wang Allen Wang - 1 month ago 22
Scala Question

save initial state of array and reset in scala

I am wondering what is the best way to save the initial state of an Array in scala so I can reset with initial values after manipulating a working copy. I would like to do something like this

val initialValue = Array(Array(1,2,3),Array(4,5,6))
val workingCopy = initialValue.clone


The problem is that when I change values of workingCopy, I also change the values of initialValue.

I also tried

val workingCopy = Array.fill(2,3)(0)
Array.copy(initialValue,0,workingCopy,2)


But I get the same result.

This holds even if i use
var
instead of
val
when defining the arrays. I think this shallow copy behavior might be caused by the nested Array structure, but I'm not sure how to deal with it.

JFo JFo
Answer

As pointed out by Angelo, you usually want to use immutable data structures to avoid problems like this. However, if you really need to go the mutable way, e.g. for performance reasons (although the "modification" of immutable collections, such as Vector, is not as expensive as you might think), then you need to do a deep copy of your nested arrays and the content. The implementation is up to you.


If it really is just an Array[Array[Int]], it's enough to do something like this:

val initialValue = Array(Array(1,2,3), Array(4,5,6))
val workingCopy = initialValue.map(_.clone)

A more general example using a reference type instead of simple Ints:

scala> class Cell(var x: String) { def copy = new Cell(x); override def toString = x }
defined class Cell

scala> val initialValue = Array(Array(new Cell("foo")))
initialValue: Array[Array[Cell]] = Array(Array(foo))

scala> val workingCopy = initialValue.map(_.map(_.copy))
workingCopy: Array[Array[Cell]] = Array(Array(foo))

scala> initialValue(0)(0).x = "bar"
initialValue(0)(0).x: String = bar

scala> initialValue
res0: Array[Array[Cell]] = Array(Array(bar))

scala> workingCopy
res1: Array[Array[Cell]] = Array(Array(foo))

Instead of initialValue.map(_.map(_.copy)), there are of course other ways to do the same thing (e.g. a nested for expression which copies the objects as its side effect).