使用默认哈希结构创建哈希的哈希。

3
我有以下代码:

我有以下代码:

default = {:id => 0, :detail =>{:name=>"Default", :id => ""}}
employees = {}

nr = (0..3).to_a 
nr.each do |n|
    employee = default
    employee[:id] = n
    employee[:detail][:name] = "Default #{n}"
    employee[:detail][:id] = "KEY-#{n}"
    employees[n] = employee
end
puts employees

我期望:detail哈希中键:id的值应为KEY-0KEY-1KEY-2


请编辑以表明您的问题。 - Cary Swoveland
3个回答

1

为了复制,您需要调用默认值

default = {id: 0, detail: {name: "Default", id:""}}
employees = {}
4.times do |n|
  employees[n] = Marshal.load(Marshal.dump(default))
  employees[n][:id] = n
  employees[n][:detail][:name] = "Default #{n}"
  employees[n][:detail][:id] = "KEY-#{n}"
end
puts employees

输出结果为

{0=>{:id=>0, :detail=>{:name=>"Default 0", :id=>"KEY-0"}}, 1=>{:id=>1, :detail=>{:name=>"Default 1", :id=>"KEY-1"}}, 2=>{:id=>2, :detail=>{:name=>"Default 2", :id=>"KEY-2"}}, 3=>{:id=>3, :detail=>{:name=>"Default 3", :id=>"KEY-3"}}}

你可以阅读这篇帖子 克隆包含内容的数组添加 这里还有一个简化版本,如果你想要更快的话。
employees = {}
4.times { |n| employees[n]={id: n, detail: {name: "Default #{n}", id:"KEY-#{n}"}} }
puts employees

1
你只需要更改以下内容:
default = { :id=>0, :detail=>{ :name=>"Default", :id=>"" } }

def default
  {}.merge(:id=>0, :detail=>({}.merge(:name=>"Default", :id=>"")))
end

但是,嘿,既然我们在做这件事,我们也可以把其他部分Ruby化:

employees = (0..3).map do |n|
    employee = default
    employee[:id] = n
    employee[:detail][:name] = "Default #{n}"
    employee[:detail][:id] = "KEY-#{n}"
    employee
end
  #=> [{:id=>0, :detail=>{:name=>"Default 0", :id=>"KEY-0"}},
  #    {:id=>1, :detail=>{:name=>"Default 1", :id=>"KEY-1"}},
  #    {:id=>2, :detail=>{:name=>"Default 2", :id=>"KEY-2"}},
  #    {:id=>3, :detail=>{:name=>"Default 3", :id=>"KEY-3"}}] 

让我们确认我们正在制作default的深层副本:

employees[0][:detail][:id] = "cat"
employees
  #=> [{:id=>0, :detail=>{:name=>"Default 0", :id=>"cat"}},
  #    {:id=>1, :detail=>{:name=>"Default 1", :id=>"KEY-1"}},
  #    {:id=>2, :detail=>{:name=>"Default 2", :id=>"KEY-2"}},
  #    {:id=>3, :detail=>{:name=>"Default 3", :id=>"KEY-3"}}] 

通常你会看到这样写:

employees = (0..3).map do |n|
  default.merge(:id=>n, :detail=>{:name=>"Default #{n}", :id=>"KEY-#{n}"})
end
  #=> [{:id=>0, :detail=>{:name=>"Default 0", :id=>"cat"}},
  #    {:id=>1, :detail=>{:name=>"Default 1", :id=>"KEY-1"}},
  #    {:id=>2, :detail=>{:name=>"Default 2", :id=>"KEY-2"}},
  #    {:id=>3, :detail=>{:name=>"Default 3", :id=>"KEY-3"}}] 

如其他答案所建议,您可以这样做:

As suggested by other answers, you could to this:

class Object
  def deep_copy
    Marshal.load(Marshal.dump(self))
  end
end

然后你可以写:

然后你可以写:

default = { :id=>0, :detail=>{ :name=>"Default", :id=>"" } }
employees = (0..3).map do |n|
  default.deep_copy.merge(:id=>n, :detail=>{:name=>"Default #{n}",
    :id=>"KEY-#{n}"})
end
  #=> [{:id=>0, :detail=>{:name=>"Default 0", :id=>"KEY-0"}},
  #    {:id=>1, :detail=>{:name=>"Default 1", :id=>"KEY-1"}},
  #    {:id=>2, :detail=>{:name=>"Default 2", :id=>"KEY-2"}},
  #    {:id=>3, :detail=>{:name=>"Default 3", :id=>"KEY-3"}}] 

这种方法的优点是,如果您更改了“默认值”,则不需要进行其他更改。

0

在每次迭代中,您都在进行浅复制,即每次都会用上一次迭代中计算出的值覆盖每个副本。您可以尝试以下方法来实现哈希内哈希默认模式的深层复制:

employee = Marshal.load(Marshal.dump(default))

演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接