2016-05-03 49 views
0

我在陣列上執行操作,我遇到了一些問題。我複製array_1分配給array_2。當我在array_2上進行操作時,uniq方法會修改原始數組。Ruby 2.3:無法複製數組。原始陣列修改

array_3是我打算做到,但我不明白爲什麼操作到那裏修改array_1

我需要一個解釋,爲什麼出現這種情況,而且我能做些什麼來防止這種情況的發生。

array_1 = [["Ed","2",],["Ann","2"],["Sue","2"],["Ed","3",],["Ann","3"],["Sue","3"]] 

array_2 = array_1.dup 
array_2 = array_2.uniq(&:first) 

array_3=[] 
array_2.each do |a2| 
    a2.pop 
    array_3.push(a2) 
end 

puts array_3 
=> [["Ed"], ["Ann"], ["Sue"]] 

puts array_1 
=> [["Ed"], ["Ann"], ["Sue"], ["Ed", "3"], ["Ann", "3"], ["Sue", "3"]] 
+0

http://ruby.about.com/od/advancedruby/a/deepcopy.htm – matt

回答

3

的問題是這一行:

array_2 = array_1.dup 

從文檔:

DUP

主要生產obj的OBJ-的實例變量的淺表副本複製,但不是它們引用的對象。

因此array_2由指向array_1中相同子陣列的指針組成。現在pop突變它的數組。所以當你poparray_2的子數組,它影響array_1相同的子陣列。

如果你說

array_2 = array_1.map(&:dup) 

個人你會得到你似乎期望的結果,不過,我會改變

a2.pop 
array_3.push(a2) 

array_3.push(a2[0]) 

我不通過改變子陣列來看你獲得了什麼(雖然也許有些事情是你沒有告訴我們的)。

+0

請不要建議人們做'Marshal.load(Marshal.dump(array_1))',或者至少提到它幾乎總是錯誤的解決方案。在這種情況下'array_1.map(&:dup)'就足夠了。 –

+0

同意,謝謝。 – matt

+0

這是更大程序的一部分。我需要保持子陣列完好無損。當我遇到問題時,我正在使用這些示例來了解ruby的內部工作原理 – ctilley79