我有以下代码:
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散列中的键:detail的值是KEY-0、KEY-1、KEY-2。
发布于 2015-07-16 22:05:26
为了复制,您将需要马歇尔默认设置。
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"}}}你可以读到这篇文章Cloning an array with its content
添加了
这里您有一个精简版本,如果您想要的话,应该会更快。
employees = {}
4.times { |n| employees[n]={id: n, detail: {name: "Default #{n}", id:"KEY-#{n}"}} }
puts employees发布于 2015-07-17 05:03:41
你只需要改变:
default = { :id=>0, :detail=>{ :name=>"Default", :id=>"" } }至
def default
{}.merge(:id=>0, :detail=>({}.merge(:name=>"Default", :id=>"")))
end但是,嘿,当我们在做的时候,我们也可以把其他的红宝石化:
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"}}] 正如其他答案所建议的那样,你可以这样做:
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"}}] 这样做的好处是,如果您更改default,则不需要进行其他更改。
发布于 2015-07-16 21:47:27
您正在每个迭代中创建一个浅拷贝,即每次都用上一次迭代中计算的值覆盖每个副本。您可以尝试下面的哈希内哈希默认模式来创建一个深度副本:
employee = Marshal.load(Marshal.dump(default))Demonstration
https://stackoverflow.com/questions/31464967
复制相似问题