2016-10-16 8 views
-3

配列の初期状態を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) 

を試してみましたしかし、私は同じ結果を得ます。

これは、配列を定義するときにvalの代わりにvarを使用しても保持されます。私は、この浅いコピーの振る舞いは、ネストされた配列構造によって引き起こされるかもしれないと思いますが、それに対処する方法がわかりません。

答えて

1

アンジェロで指摘したように、あなたは通常、このような問題を回避するために、不変のデータ構造を使用します。しかし、実際に変更可能な方法、たとえばパフォーマンス上の理由から(Vectorのような不変なコレクションの「変更」はあなたが考えるほど高価ではありませんが)、ネストされた配列のと内容をディープコピーする必要があります。実装はあなた次第です。


それは本当にただArray[Array[Int]]であれば、それはこのような何かを行うのに十分だ:

:代わりにシンプルInt Sの参照型を使用して

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

より一般的な例

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

0

varvalは、参照が不変かどうかを実際に判断するだけで、データ構造の内容には影響しません。たとえば、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)) 
+0

ほとんどの場合、不変のデータ構造を使いたいと思います。しかし、私のデータは、再帰関数を呼び出すための本当に大きな行列です。関数を再帰的に呼び出すたびに、または毎回引数を渡すたびに新しいオブジェクトを作成したくありません。その場で変更する)。 –

+1

その場合、初期値を不変のリストにして、配列(または他の可変構造)に変換して作業コピーを得ることができます。 –

関連する問題