元の配列に影響を与えずに、配列のコピーを作成し、そのコピーをインプレースで変更したい。このコードは失敗します
a = [
'462664',
'669722',
'297288',
'796928',
'584497',
'357431'
]
b = a.clone
b.object_id == a.object_id # => false
a[1][2] = 'X'
a[1] #66X722
b[1] #66X722
コピーはオブジェクトとは異なる必要があります。単なる参照のように振る舞うのはなぜですか?
アレイのディープコピーを行う必要があります。
ここにそれを行う方法があります
Marshal.load(Marshal.dump(a))
これは、配列のクローンを作成しているが、内部の要素は複製していないためです。そのため、配列オブジェクトは異なりますが、含まれる要素は同じインスタンスです。たとえば、a.each{|e| b << e.dup}
あなたのケース
配列自体でclone
を呼び出す代わりに、map
を使用して配列の各要素で呼び出すことができます。
b = a.map(&:clone)
配列内の各要素の新しいインスタンスを取得するため、これは質問で述べた例で機能します。
これを試して:
b = [] #create a new array
b.replace(a) #replace the content of array b with the content from array a
この時点で、これらの2つの配列は異なるオブジェクトへの参照であり、内容は同じです。
#dupを使用すると、オブジェクトの浅いコピーが作成されます。つまり、「オブジェクトのインスタンス変数はコピーされますが、オブジェクトが参照するオブジェクトはコピーされません」。例えば:
a = [1, 2, 3]
b = a.dup
b # => [1, 2, 3]
ソース: https://Ruby-doc.org/core-2.5.3/Object.html#method-i-dup
編集:私の下のポールの話を聞いてください。その質問を誤解した。
これが他の場所で回答されているかどうかは不明です。検索を試みたが成功しなかった。
これを試して
current_array =["a", "b","c","d"]
new_array = current_array[0 .. current_array.length]
new_array[0] ="cool"
output of new_array
"cool","b","c","d"
お役に立てれば。