保存数组的初始状态并在scala中重置

时间:2016-10-16 17:58:38

标签: scala

我想知道在scala中保存数组初始状态的最佳方法是什么,这样我可以在操作工作副本后重置初始值。我想做这样的事情

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

问题在于,当我更改workingCopy的值时,我也会更改initialValue的值。

我也试过

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

但我得到的结果相同。

即使我在定义数组时使用var而不是val,这也成立。我认为这种浅层复制行为可能是由嵌套数组结构引起的,但我不确定如何处理它。

2 个答案:

答案 0 :(得分:1)

正如Angelo所指出的,您通常希望使用不可变数据结构来避免这样的问题。但是,如果你真的需要采取可变的方式,例如出于性能原因(尽管不可变集合的“修改”,例如Vector,并不像您想象的那么昂贵),那么您需要对嵌套数组执行深层复制和内容。实施取决于您。

如果它真的只是一个Array[Array[Int]],就足以做到这样的事情:

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

使用引用类型而不是简单Int的更一般的示例:

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))

而不是initialValue.map(_.map(_.copy)),当然还有其他方法可以做同样的事情(例如,嵌套的for表达式将对象复制为副作用。)

答案 1 :(得分:0)

var vs val实际上只是确定引用是否是不可变的,它对数据结构的内容没有影响。如果要转换为不可变数据结构,例如List,那么副本将不再需要作为"修改"的操作。这种结构的内容创造了一个新的参考,使原始结构不受影响。

例如:

val initialValue = List(List(1,2,3),List(4,5,6))

val sumInnerLists = initialValue.map(l => l.foldLeft(0)(_ + _))

println(sumInnerLists) // List(6, 15)
println(initialValue)  // List(List(1,2,3),List(4,5,6))