在ruby中修改副本时实际哈希被修改

时间:2016-03-17 06:50:20

标签: ruby hash

我正在尝试复制Hash,然后再修改hash的副本。但是当我将副本与原始副本进行比较时,即使原始哈希值也会被修改。 我尝试过使用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

哈希对象(我想复制并保持其原始版本未修改):

@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都会更新。 请帮帮忙,我从现在开始一小时尝试这个。

4 个答案:

答案 0 :(得分:1)

我认为您需要在此处执行deep_dup以将一个哈希内容与另一个哈希内容完全分开。

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

答案 1 :(得分: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

答案 2 :(得分: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

答案 3 :(得分: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的更多信息,请参阅此内容。