ruby - Create hash-of-hashes using structure of the default hash -
i have following code:
default = {:id => 0, :detail =>{:name=>"default", :id => ""}} employees = {} nr = (0..3).to_a nr.each |n| employee = default employee[:id] = n employee[:detail][:name] = "default #{n}" employee[:detail][:id] = "key-#{n}" employees[n] = employee end puts employees
i expect values key :id
in :detail
hash key-0
, key-1
, key-2
.
you need change:
default = { :id=>0, :detail=>{ :name=>"default", :id=>"" } }
to
def default {}.merge(:id=>0, :detail=>({}.merge(:name=>"default", :id=>""))) end
but, hey, while we're @ may ruby-ize rest:
employees = (0..3).map |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"}}]
let's confirm making deep copies of 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"}}]
you'd more commonly see written:
employees = (0..3).map |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 other answers, this:
class object def deep_copy marshal.load(marshal.dump(self)) end end
then write:
default = { :id=>0, :detail=>{ :name=>"default", :id=>"" } } employees = (0..3).map |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"}}]
this has advantage that, if change default
, no other changes needed.
Comments
Post a Comment