web-dev-qa-db-ja.com

内容を含む配列の複製

元の配列に影響を与えずに、配列のコピーを作成し、そのコピーをインプレースで変更したい。このコードは失敗します

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

コピーはオブジェクトとは異なる必要があります。単なる参照のように振る舞うのはなぜですか?

14
Redouane Red

アレイのディープコピーを行う必要があります。

ここにそれを行う方法があります

Marshal.load(Marshal.dump(a))

これは、配列のクローンを作成しているが、内部の要素は複製していないためです。そのため、配列オブジェクトは異なりますが、含まれる要素は同じインスタンスです。たとえば、a.each{|e| b << e.dup}あなたのケース

15
jazzytomato

配列自体でcloneを呼び出す代わりに、mapを使用して配列の各要素で呼び出すことができます。

b = a.map(&:clone)

配列内の各要素の新しいインスタンスを取得するため、これは質問で述べた例で機能します。

14
wjordan

これを試して:

b = [] #create a new array 
b.replace(a) #replace the content of array b with the content from array a

この時点で、これらの2つの配列は異なるオブジェクトへの参照であり、内容は同じです。

6
Maya Novarini

#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

編集:私の下のポールの話を聞いてください。その質問を誤解した。

3
Zachary White

これが他の場所で回答されているかどうかは不明です。検索を試みたが成功しなかった。

これを試して

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"

お役に立てれば。

0
Anutosh