访问ruby中嵌套散列的元素 [英] Accessing elements of nested hashes in ruby

查看:31
本文介绍了访问ruby中嵌套散列的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个用 ruby​​ 编写的小实用程序,它广泛使用了嵌套哈希.目前,我正在检查对嵌套哈希元素的访问,如下所示:

I'm working a little utility written in ruby that makes extensive use of nested hashes. Currently, I'm checking access to nested hash elements as follows:

structure = { :a => { :b => 'foo' }}

# I want structure[:a][:b]

value = nil

if structure.has_key?(:a) && structure[:a].has_key?(:b) then
  value = structure[:a][:b]
end

有没有更好的方法来做到这一点?我想说:

Is there a better way to do this? I'd like to be able to say:

value = structure[:a][:b]

如果 :a 不是 structure 中的键,则得到 nil

And get nil if :a is not a key in structure, etc.

推荐答案

这些天我通常这样做的方式是:

The way I usually do this these days is:

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

这将为您提供一个散列,该散列创建一个新散列作为缺失键的条目,但对于第二级键返回 nil:

This will give you a hash that creates a new hash as the entry for a missing key, but returns nil for the second level of key:

h['foo'] -> {}
h['foo']['bar'] -> nil

您可以嵌套它以添加可以通过这种方式解决的多个层:

You can nest this to add multiple layers that can be addressed this way:

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

h['bar'] -> {}
h['tar']['zar'] -> {}
h['scar']['far']['mar'] -> nil

您也可以使用 default_proc 方法无限期地链接:

You can also chain indefinitely by using the default_proc method:

h = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }

h['bar'] -> {}
h['tar']['star']['par'] -> {}

上面的代码创建了一个哈希,它的默认过程创建了一个具有相同默认过程的新哈希.因此,在查找未见过的键时作为默认值创建的哈希将具有相同的默认行为.

The above code creates a hash whose default proc creates a new Hash with the same default proc. So, a hash created as a default value when a lookup for an unseen key occurs will have the same default behavior.

更多细节

Ruby 哈希允许您控制在查找新键时如何创建默认值.指定时,此行为被封装为 Proc 对象并可通过 default_procdefault_proc= 方法.也可以通过将块传递给 Hash 来指定默认 proc.new.

Ruby hashes allow you to control how default values are created when a lookup occurs for a new key. When specified, this behavior is encapsulated as a Proc object and is reachable via the default_proc and default_proc= methods. The default proc can also be specified by passing a block to Hash.new.

让我们稍微分解一下这段代码.这不是惯用的 ruby​​,但将其分成多行更容易:

Let's break this code down a little. This is not idiomatic ruby, but it's easier to break it out into multiple lines:

1. recursive_hash = Hash.new do |h, k|
2.   h[k] = Hash.new(&h.default_proc)
3. end

第 1 行将变量 recursive_hash 声明为一个新的 Hash 并开始一个块作为 recursive_hashdefault_proc.该块传递了两个对象:h,它是正在执行键查找的 Hash 实例,以及 k,正在查找的键

Line 1 declares a variable recursive_hash to be a new Hash and begins a block to be recursive_hash's default_proc. The block is passed two objects: h, which is the Hash instance the key lookup is being performed on, and k, the key being looked up.

第 2 行将散列中的默认值设置为一个新的 Hash 实例.这个散列的默认行为是通过传递一个从 default_proc 创建的 Proc 来提供的;即,块本身定义的默认过程.

Line 2 sets the default value in the hash to a new Hash instance. The default behavior for this hash is supplied by passing a Proc created from the default_proc of the hash the lookup is occurring in; ie, the default proc the block itself is defining.

以下是 IRB 会议的示例:

Here's an example from an IRB session:

irb(main):011:0> recursive_hash = Hash.new do |h,k|
irb(main):012:1* h[k] = Hash.new(&h.default_proc)
irb(main):013:1> end
=> {}
irb(main):014:0> recursive_hash[:foo]
=> {}
irb(main):015:0> recursive_hash
=> {:foo=>{}}

recursive_hash[:foo] 的散列被创建时,它的 default_procrecursive_hashdefault_proc 提供代码>.这有两个影响:

When the hash at recursive_hash[:foo] was created, its default_proc was supplied by recursive_hash's default_proc. This has two effects:

  1. recursive_hash[:foo] 的默认行为与 recursive_hash 相同.
  2. recursive_hash[:foo]default_proc 创建的散列的默认行为将与 recursive_hash 相同.
  1. The default behavior for recursive_hash[:foo] is the same as recursive_hash.
  2. The default behavior for hashes created by recursive_hash[:foo]'s default_proc will be the same as recursive_hash.

因此,继续在 IRB 中,我们得到以下内容:

So, continuing in IRB, we get the following:

irb(main):016:0> recursive_hash[:foo][:bar]
=> {}
irb(main):017:0> recursive_hash
=> {:foo=>{:bar=>{}}}
irb(main):018:0> recursive_hash[:foo][:bar][:zap]
=> {}
irb(main):019:0> recursive_hash
=> {:foo=>{:bar=>{:zap=>{}}}}

这篇关于访问ruby中嵌套散列的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆