2016-09-28 54 views
-1

以下是Ruby bug还是完全正常的?Ruby散列错误,异常或正常?

> a = [1, 2, 3].zip([[]]*3).to_h 
=> {1=>[], 2=>[], 3=>[]} 
> a[1] << 2 
=> [2] 
> a 
=> {1=>[2], 2=>[2], 3=>[2]} 

我不希望所有的值的话,被2附加我只是为了在关键的是1的地方添加2

+3

在Python中,这是因为'[[]] * 3'导致列表中有三个相同的列表(同一对象)。因此,当您追加到它时,它会显示在所有的按键中。使用'[[],[],[]]'不会导致这个问题,但我不知道足够的Ruby知道它是否相同。 –

+0

散列中每个值的对象_id是什么? –

+0

他们都有相同的'object_id' – Lokesh

回答

4

预计,当你在zip创建第二个阵列,因为是同一个对象:

a = [1, 2, 3].zip([[]]*3) 
#=> [[1, []], [2, []], [3, []]] 
a.map{|aa| aa.last.object_id } 
#=> [70307853627580, 70307853627580, 70307853627580] 

所以,当你试图更新的对象,它就会反映在物体a

a[0][1] << 2 
#=> [2] 
p a 
#=> [[1, [2]], [2, [2]], [3, [2]]] 

要创建带有单独对象的array,可以改为传递一个块。此法安全与可变对象,如哈希值,字符串或其他阵列使用:

a = [1, 2, 3].zip(Array.new(3) { [] }) 
#=> [[1, []], [2, []], [3, []]] 
a[0][1] << 2 
#=> [2] 
p a 
#=> [[1, [2]], [2, []], [3, []]] 

我建议你阅读this article其中谈到这样的情况下由亚伦帕特森哈希值。

+0

很好的详细解释1+ –