34

在 Ruby 中创建散列的散列允许方便的二维(或更多)维查找。但是,插入时必须始终检查第一个索引是否已存在于哈希中。例如:

h = Hash.new
h['x'] = Hash.new if not h.key?('x')
h['x']['y'] = value_to_insert

最好在自动创建新哈希的情况下执行以下操作:

h = Hash.new
h['x']['y'] = value_to_insert

同样,在查找第一个索引不存在的值时,如果返回 nil 而不是接收未定义的“[]”错误方法会更好。

looked_up_value = h['w']['z']

可以创建一个具有此行为的 Hash 包装类,但是否存在用于完成此任务的 Ruby 习语?

4

2 回答 2

54

您可以向Hash.new函数传递一个块,该块被执行以产生默认值,以防查询的值尚不存在:

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

当然,这可以递归地完成。有一篇文章解释了细节

为了完整起见,这里是文章中任意深度哈希的解决方案:

hash = Hash.new(&(p = lambda{|h, k| h[k] = Hash.new(&p)}))

最初提出这个解决方案的人是Kent Sibilev

于 2008-10-04T12:16:03.567 回答
4

所谓的自动复活,既是福也是祸。问题可能在于,如果您在定义之前“查看”一个值,您会被插槽中的这个空哈希卡住,您需要稍后将其修剪掉。

如果您不介意一点无政府状态,您总是可以插入或等于样式声明,这将允许您在查询时构造预期的结构:

((h ||= { })['w'] ||= { })['z']
于 2009-04-11T04:24:11.143 回答