红宝石中哈希成语的哈希?

时间:2008-10-04 12:10:08

标签: ruby idioms hash-of-hashes

在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习惯用法?

3 个答案:

答案 0 :(得分:54)

您可以将Hash.new函数传递给执行的块,以便在查询的值不存在时产生默认值:

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

当然,这可以递归完成。

/编辑:哇,有an article回答这个问题。

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

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

积分从Data Noise转到肯特。

答案 1 :(得分:4)

自称为自我毁灭,既是一种祝福,也是一种诅咒。问题可能是,如果你在定义之前“查看”一个值,你就会在插槽中使用这个空哈希,你需要稍后将其删除。

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

((h ||= { })['w'] ||= { })['z']

答案 2 :(得分:0)

require 'xkeys'
h = {}.extend XKeys::Hash

h['x', 'y'] = value_to_insert
looked_up_value = h['w', 'z'] # nil

h[:foo, :bar, :baz, :else => 0] += 1