正如this answer中所述,Array.new(size, object)
创建了一个对同一size
object
提及hash = Hash.new
a = Array.new(2, hash)
a[0]['cat'] = 'feline'
a # => [{"cat"=>"feline"},{"cat"=>"feline"}]
a[1]['cat'] = 'Felix'
a # => [{"cat"=>"Felix"},{"cat"=>"Felix"}]
的数组。
dup
为什么Ruby会这样做,而不是clone
的{{1}}或object
?
答案 0 :(得分:9)
因为这是the documentation所说的。请注意Hash.new
只被调用一次,所以当然只有一个Hash
如果要为数组中的每个元素创建一个新对象,请将块传递给Array.new
方法,并为每个新元素调用该块:
>> a = Array.new(2) { Hash.new }
=> [{}, {}]
>> a[0]['cat'] = 'feline'
=> "feline"
>> a
=> [{"cat"=>"feline"}, {}]
>> a[1]['cat'] = 'Felix'
=> "Felix"
>> a
=> [{"cat"=>"feline"}, {"cat"=>"Felix"}]
答案 1 :(得分:2)
对于某些无法就地修改的类(如Fixnum
s),Array.new(X, object)
表单按预期工作,可能更有效(它只调用memfill
而不是rb_ary_store
和yield
到街区):
对于更复杂的对象,您始终拥有阻止形式(例如Array.new(5) { Hash.new }
)。
* 编辑:*根据评论进行修改。抱歉这个愚蠢的例子,我写这篇文章的时候累了。
答案 2 :(得分:0)
我想出了这个答案,非常简短的解决方案
c_hash = Hash.new
["a","b","c","d","e","f"].each do |o|
tmp = Hash.new
[1,2,3].map {|r| tmp[r] = Array.new}
c_hash[o] = tmp
end
c_hash['a'][1] << 10
p c_hash