Ruby - 访问多维哈希并避免访问零对象 [英] Ruby - Access multidimensional hash and avoid access nil object

查看:129
本文介绍了Ruby - 访问多维哈希并避免访问零对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能存在重复:

Ruby:在IF语句中使用Nils


假设我尝试访问这样的哈希:

  my_hash ['key1'] ['key2'] ['key3'] 

如果key1,key2和key3存在于散列表中,那么这很好,但是如果key1不存在呢?



然后我得到 NoMethodError:undefined method [] for nil:NilClass



到目前为止,我正在处理这样一个条件如:

if my_hash ['key1']&& my_hash ['key1'] ['key2'] ...



这是否合适?是否还有其他Rubiest方法?

解决方案

如果您使用Ruby 2.3或更高版本,您可以使用挖掘

  my_hash.dig('key1','key2','key3')

很多人坚持使用普通的ruby,并链接&&< / code> guard测试。 / p>

您可以使用stdlib $ rel =noreferrer> Hash#fetch 也是:

  my_hash.fetch('key1',{} ).fetch('key2',{})。fetch('key3',nil)

如链接ActiveSupport的 #try 方法。

  my_hash.try(:[],'key1')。try(:[],'key2')。try(:[],'key3') 

其他人使用 andand

  myhash ['key1'] .and and ['key2'] .andand [' key3'] 

有些人认为自我中心nils 是一个好主意(尽管有人会狩猎你,如果他们发现你这样做会折磨你)。

  class NilClass 
def method_missing(* args);零; end
end

my_hash ['key1'] ['key2'] ['key3']

您可以使用可枚举#reduce (或别名注入)。

  ['key1','key2','key3' ] .reduce(my_hash){| m,k | m&& amp;&或者可能扩展哈希或只是你的目标哈希对象与嵌套查找方法 / p> 

  module NestedHashLookup 
def nest * keys
keys.reduce(self){| m,k | m&& amp;& m [k]}
结束
结束

my_hash.extend(NestedHashLookup)
my_hash.nest'key1','key2','key3'

哦,我们怎么能忘记 maybe monad?

  Maybe.new(my_hash)['key1'] ['key2'] ['key3'] 


Possible Duplicate:
Ruby: Nils in an IF statement
Is there a clean way to avoid calling a method on nil in a nested params hash?

Let's say I try to access a hash like this:

my_hash['key1']['key2']['key3']

This is nice if key1, key2 and key3 exist in the hash(es), but what if, for example key1 doesn't exist?

Then I would get NoMethodError: undefined method [] for nil:NilClass. And nobody likes that.

So far I deal with this doing a conditional like:

if my_hash['key1'] && my_hash['key1']['key2'] ...

Is this appropriate, is there any other Rubiest way of doing so?

解决方案

There are many approaches to this.

If you use Ruby 2.3 or above, you can use dig

my_hash.dig('key1', 'key2', 'key3')

Plenty of folks stick to plain ruby and chain the && guard tests.

You could use stdlib Hash#fetch too:

my_hash.fetch('key1', {}).fetch('key2', {}).fetch('key3', nil)

Some like chaining ActiveSupport's #try method.

my_hash.try(:[], 'key1').try(:[], 'key2').try(:[], 'key3')

Others use andand

myhash['key1'].andand['key2'].andand['key3']

Some people think egocentric nils are a good idea (though someone might hunt you down and torture you if they found you do this).

class NilClass
  def method_missing(*args); nil; end
end

my_hash['key1']['key2']['key3']

You could use Enumerable#reduce (or alias inject).

['key1','key2','key3'].reduce(my_hash) {|m,k| m && m[k] }

Or perhaps extend Hash or just your target hash object with a nested lookup method

module NestedHashLookup
  def nest *keys
    keys.reduce(self) {|m,k| m && m[k] }
  end
end

my_hash.extend(NestedHashLookup)
my_hash.nest 'key1', 'key2', 'key3'

Oh, and how could we forget the maybe monad?

Maybe.new(my_hash)['key1']['key2']['key3']

这篇关于Ruby - 访问多维哈希并避免访问零对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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