2016-03-17 25 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