2016-03-17 34 views
2

我試圖複製哈希,然後修改哈希的副本。但是,當我將原始副本與原始副本進行比較時,即使原始哈希值正在被修改。 我一直在使用this嘗試:當在紅寶石中修改副本時,實際哈希得到修改

def deep_copy(o) 
    Marshal.load(Marshal.dump(o)) 
end 

h1 = {:a => 'foo'} 
h2 = deep_copy(h1) 
h1[:a] << 'bar' 
p h2 

我也想這樣做this

def dumpable_hash(h) 
    return h unless h.default_proc 
    copy = h.clone 
    copy.default = nil # clear the default_proc 
    copy 
end 

Hash對象(這是我要複製並保持其原始未修改):

@original = {0=>{0=>[0, 4, 5, 6], 2=>[3, 7], 1=>[1, 2]}, 1=>{0=>[0, 4, 5, 6], 2=>[1], 1=>[2, 3, 7]}, 2=>{0=>[0, 4, 6], 1=>[1, 2, 5], 2=>[3, 7]}, 3=>{0=>[0, 4], 2=>[1, 2, 3, 6, 7], 1=>[5]}, 4=>{0=>[4], 2=>[1, 5], 1=>[2, 3, 6, 7, 0]}, 5=>{1=>[0, 1, 2, 5], 2=>[3, 6, 7], 0=>[4]}, 6=>{1=>[0, 1, 2, 5, 4], 2=>[3, 6, 7], 0=>[]}} 

嘗試將原件複製到另一個對象中,並使用給定的答案。

方法用於更新其克隆,

#outer loop 
(1..5).each do |i| 
#assigning original to another object in every loop 
copy = @original.clone 
     (-6..0).each do |row|      
      if copy[row.abs][0].include? k 
       copy[row.abs][0] -= [k] 
       copy[row.abs][1] += [k] 
       puts "row #{row.abs}, col #{k}" 
       break 
      end 
     end 
    end 

當循環結束雙方originalcopy被更新。 請幫助,我一直在嘗試從一個小時。

+0

您使用的是哪個版本的ruby(或irb?)?我已經用ruby 1.9.3,2.0和2.3版試過了你的deep_copy()例子,但是我沒有看到任何問題。也許你也可以更明確地看到你所看到的問題。 – peak

+0

我仍然無法修復它,我想這是因爲嵌套散列。 – sahil

+0

@peak,請檢查更新後的問題。 – sahil

回答

1

如果想要將一個散列複製到另一個散列,可以像這樣做。然後你可以操作複製的散列,甚至可以在循環中完成。然後爲你的任務操縱複製的散列。在這裏它複製散列的鍵值對,

@original = {0=>{0=>[0, 4, 5, 6], 2=>[3, 7], 1=>[1, 2]}, 1=>{0=>[0, 4, 5, 6], 2=>[1], 1=>[2, 3, 7]}, 2=>{0=>[0, 4, 6], 1=>[1, 2, 5], 2=>[3, 7]}, 3=>{0=>[0, 4], 2=>[1, 2, 3, 6, 7], 1=>[5]}, 4=>{0=>[4], 2=>[1, 5], 1=>[2, 3, 6, 7, 0]}, 5=>{1=>[0, 1, 2, 5], 2=>[3, 6, 7], 0=>[4]}, 6=>{1=>[0, 1, 2, 5, 4], 2=>[3, 6, 7], 0=>[]}} 
copy = Hash.new 
@original.each do |k, v| 
    copy[k] = v.dup  
end 
p copy #prints the copied hash 
+0

非常感謝。它通過使用循環複製散列來工作。 – sahil

1

我認爲你需要在這裏做deep_dup來將一個散列內容與另一個完全分開。

h1 = {a: "foo"} 
h2 = h1.deep_dup 
h2[:a] << "bar" 
puts h2 #returns {:a => "foobar"} 
puts h1 # returns {:a => "foo"} 
+0

如果我使用deep_dup,它說'未定義的方法\ deep_dup'爲#(NoMethodError)\''。我正在嘗試解決在線編碼環境中的問題,並且無法加載任何外部庫。 – sahil

+0

deep_dup僅支持主動支持 – Mohamad

0

您正在修改原始散列(附加到h1散列)。修改複製深之一,你可以看到原來是因爲之前住,

def deep_copy(o) 
    Marshal.load(Marshal.dump(o)) 
end 
h1 = {:a => 'foo'} 
h2 = deep_copy(h1) 
h2[:a] << 'bar' 
p h2 #prints the cloned one 
p h1 #prints the original one 

約編組庫here futher信息,請參閱本。

+0

我得到這個錯誤,''''轉儲':不能轉儲散列與默認proc(TypeError)'' – sahil

+0

你能澄清,你在哪個在線編碼環境? – reznov9185

+0

現在我無法在我的本地環境中執行此操作,如果您可以嘗試我在問題中給出的上述示例,因爲我無法執行此操作。可能是我錯過了什麼? – sahil

1

使用dup

h1 = {a:1, b:2} 
h2 = h1.dup 
h2[:c] = 3 
puts h1 
{:a=>1, :b=>2} 
puts h2 
{:a=>1, :b=>2, :c=>3} 

如果您有嵌套散列,您可以使用ActiveSupport deep_dup

def deep_dup 
    each_with_object(dup) do |(key, value), hash| 
    hash[key.deep_dup] = value.deep_dup 
    end 
end