创建一个哈希表,其中值为数组,初始默认值为空数组。

49
我想在Ruby中创建一个哈希表,并将默认值设置为空数组。
因此,我编写了以下代码:
x = Hash.new([])

然而,当我尝试将一个值推入其中时

x[0].push(99)

所有的键都会被推入那个数组中,值为99。我该如何解决这个问题?


2
Hash.new { [] } 是你想要的。 - Cary Swoveland
6
@CarySwoveland 这将返回一个新的数组,而不将其存储在哈希表中。 - Stefan
1
如果您通过|=(例如x [0] | = [99])添加值,则可以使用x = Hash.new { [] },因为它将创建一个新数组并将其分配给x [0]。我认为最好像下面的答案那样明确说明。 - dinjas
2个回答

90

Lakshmi是正确的。当你使用Hash.new([])创建哈希时,你创建了一个数组对象。

因此,在哈希中的每个缺失的键上都返回相同的数组。

这就是为什么,如果编辑共享数组,则所有缺失的键都会反映出变化。

使用:

Hash.new { |h, k| h[k] = [] }
创建并为哈希中的每个缺失的键分配一个数组,以便它是一个唯一的对象。

1
Hash.new(Array.new)Hash.new{Array.new}有什么区别? - vildhjarta
2
@vildhjarta Hash.new(Array.new) 只创建一次数组,然后将新数组传递给哈希构造函数,因此所有缺失的对象共享同一个数组。Hash.new {Array.new} 每次调用块 ({Array.new}) 都会创建一个新数组,这为每个缺失的对象产生一个新数组。 - Myst

33
h = Hash.new{|h,k| h[k] = [] }

h[0].push(99)

这会导致{0=>[99]}的结果。


当使用Hash.new([])时,一个单一的对象被用作默认值(即在哈希键h[0]没有返回任何内容时返回的值),在这种情况下是一个数组。

所以当我们说h[0].push(99)时,它将99推入该数组,但不会为h[0]分配任何东西。因此,如果输出h,您仍将看到一个空哈希{},而默认对象将为[99]


而当提供一个块即Hash.new{|h,k| h[k] = [] }时,每次需要默认值时都会创建一个新的对象并分配给h[k]

h[0].push(99)会为其分配h[0] = []并将值推入该新数组。


这很令人困惑。Hash.new([]) 创建一个对象并将其分配给所有新条目。Hash.new{} 为每个条目创建一个对象并立即丢弃它;它等同于 Hash.new(nil)。 - cabo

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