Ruby 中的哈希习语的哈希值?

发布于 2024-07-07 09:57:43 字数 451 浏览 5 评论 0原文

在 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']

人们可以创建一个具有此行为的哈希包装类,但是是否有现有的 Ruby 习惯用法可以完成此任务?

Creating hashes of hashes in Ruby allows for convenient two (or more) dimensional lookups. However, when inserting one must always check if the first index already exists in the hash. For example:

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

It would be preferable to do the following where the new Hash is created automatically:

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

Similarly, when looking up a value where the first index doesn't already exist, it would be preferable if nil is returned rather than receiving an undefined method for '[]' error.

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

One could create a Hash wrapper class that has this behavior, but is there an existing a Ruby idiom for accomplishing this task?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2024-07-14 09:57:43

您可以传递 Hash.new 执行一个块,如果查询的值尚不存在,则执行该块以产生默认值:

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

当然,这可以递归地完成。 有 一篇解释详细信息的文章

为了完整起见,以下是文章中针对任意深度哈希的解决方案:

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

最初提出此解决方案的人是 Kent西比廖夫。

You can pass the Hash.new function a block that is executed to yield a default value in case the queried value doesn't exist yet:

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

Of course, this can be done recursively. There's an article explaining the details.

For the sake of completeness, here's the solution from the article for arbitrary depth hashes:

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

The person to originally come up with this solution is Kent Sibilev.

迷爱 2024-07-14 09:57:43

正如它所称的,自动复活既是福也是祸。 问题可能在于,如果您在定义之前“查看”一个值,那么您将陷入槽中的空散列,并且需要稍后将其删除。

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

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

Autovivification, as it's called, is both a blessing and a curse. The trouble can be that if you "look" at a value before it's defined, you're stuck with this empty hash in the slot and you would need to prune it off later.

If you don't mind a bit of anarchy, you can always just jam in or-equals style declarations which will allow you to construct the expected structure as you query it:

((h ||= { })['w'] ||= { })['z']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文