本文介绍了在ruby中访问嵌套哈希的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我正在开发一个用ruby编写的实用程序,它广泛使用嵌套哈希。目前,我正在检查对嵌套散列元素的访问,如下所示: structure = {:a => {:b => 'foo'}} #我想要structure [:a] [:b] value = nil 如果structure.has_key?( :a)&& structure [:a] .has_key?(:b)then value = structure [:a] [:b] end 有没有更好的方法来做到这一点?我希望能够说: $ p $ value = structure [:a] [:b] 获得 nil 如果:a不是 structure 等 解决方案我通常这样做的方式是: h = Hash.new {| h,k | h [k] = {}} 这会给你一个散列,输入一个缺失的密钥,但返回nil为第二级密钥: h ['foo'] - > {} h ['foo'] ['bar'] - > nil 你可以嵌套这个来添加可以用这种方式处理的多个图层: 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 方法: h = Hash.new {| h,k | h [k] = Hash.new(& h.default_proc)} h ['bar'] - > {} h ['tar'] ['star'] ['par'] - > {} 上面的代码创建了一个散列,其默认proc使用相同的默认proc创建一个新的散列。因此,在查找不可见密钥时,创建默认值的哈希将具有相同的默认行为。 编辑:更多详细信息 Ruby哈希允许您控制在查找新密钥时如何创建默认值。指定时,此行为被封装为 Proc 对象,并可通过 default_proc 和 default_proc = 方法。默认的proc也可以通过将一个块传递给 Hash.new 。 让我们稍微分解一下这段代码。这不是惯用的ruby,但更容易分成多行: 1。 recursive_hash = Hash.new do | h,k | 2. h [k] = Hash.new(& h.default_proc) 3. end 第1行声明一个变量 recursive_hash 为一个新的 Hash 并开始一个块为 recursive_hash 的 default_proc 。该块传递两个对象: h ,这是执行密钥查找的 Hash 实例,而 第2行将散列中的默认值设置为一个新的 k ,该键被查找。 $ c> Hash 实例。这个散列的缺省行为是通过传递从 default_proc 创建的 Proc ;即,块本身正在定义的默认proc。 以下是IRB会话的示例: IRB(主):011:0> recursive_hash = Hash.new do | h,k | irb(main):012:1 * h [k] = Hash.new(& h.default_proc) irb(main):013:1>结束 => {} irb(main):014:0> recursive_hash [:foo] => {} irb(main):015:0> recursive_hash => {:foo => {}} 在 recursive_hash [ :foo] 被创建,它的 default_proc 由 recursive_hash 的 default_proc 。这有两个作用: recursive_hash [:foo] 的默认行为是与相同。recursive_hash 。 由 recursive_hash [:foo] 的 default_proc 将与 recursive_hash 相同。 ol> 因此,继续在IRB中,我们得到以下结果: irb主要):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 => {}}}} 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 = nilif structure.has_key?(:a) && structure[:a].has_key?(:b) then value = structure[:a][:b]endIs there a better way to do this? I'd like to be able to say:value = structure[:a][:b]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] = {} }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'] -> nilYou 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'] -> nilYou 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.EDIT: More detailsRuby 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.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. endLine 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.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.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=>{}}When the hash at recursive_hash[:foo] was created, its default_proc was supplied by recursive_hash's default_proc. This has two effects:The default behavior for recursive_hash[:foo] is the same as recursive_hash.The default behavior for hashes created by recursive_hash[:foo]'s default_proc will be the same as recursive_hash.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中访问嵌套哈希的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-18 13:21