Ruby on rails 有没有更好的Ruby或Rails习惯用法来检查嵌套哈希中是否存在值?

Ruby on rails 有没有更好的Ruby或Rails习惯用法来检查嵌套哈希中是否存在值?,ruby-on-rails,ruby,hash,Ruby On Rails,Ruby,Hash,如果该值为: myhash['first_key']['second_key'] 存在,那么我需要得到它。但是“第二个\u键”可能根本不存在于我的\u散列中,如果不存在,我不希望该行抛出异常 现在我用一个丑陋的条件来包装整个事情,就像这样: if myhash['first_key'].present? and myhash['first_key']['second_key'].present? ... end 我相信一定有更简单的方法。您可以随时使用试试: hsh.try(:[], '

如果该值为:

myhash['first_key']['second_key']
存在,那么我需要得到它。但是
“第二个\u键”
可能根本不存在于
我的\u散列中,如果不存在,我不希望该行抛出异常

现在我用一个丑陋的条件来包装整个事情,就像这样:

if myhash['first_key'].present? and myhash['first_key']['second_key'].present?
  ...
end

我相信一定有更简单的方法。

您可以随时使用
试试

hsh.try(:[], 'first_key').try(:[], 'second_key')

仅供参考:如果您正在进行大量此类检查,您可能希望重构代码以避免这些情况。

如果有疑问,请编写一个包装:

h={
第一个按键:{
第二个键:“测试”
}
}
类散列
def fetch_路径(*部分)
零件。减少(自身)do |备忘录,键|
备注[键]如果是备注
结束
结束
结束
h、 获取路径(:第一个_键,:第二个_键)#=>“测试”
h、 获取路径(:第一个键,:第三个键)#=>nil
h、 获取路径(:第一个密钥,:第三个密钥,:第四个密钥)#=>nil
h、 获取路径(:foo,:第三个_键)#=>nil

您可以在处理哈希之前设置一些默认值。比如:

myhash[:first_key] ||= {}

if myhash[:first_key][:second_key]
  # do work
end

试试这个干净干净的溶液。哈希默认值:

h = Hash.new( {} ) # sets a hash as default value
现在做你喜欢的事:

h[:some_key] # => {}
h[:non_existent_key][:yet_another_non_existent_key] # => nil
很好

假设您有一个已填充的现有哈希:

h = { a: 1, b: 2, c: 3 }
因此,您只需将其默认值设置为返回一个新哈希:

h.default = {}
你又来了:

h[:d] # => {}
h[:d][:e] # => nil

为什么不为此定义一个方法呢

class Hash
  def has_second_key?(k1,k2)
    self[k1] ? self[k1][k2] : nil
  end
end
new_hash = {}
new_hash["a"] = "b"
new_hash["c"] = {"d"=>"e","f"=>"g"}
new_hash[:p] = {q:"r"}
new_hash.has_second_key?("r","p")
  # =>nil
new_hash.has_second_key?("c","f")
  # =>"g"
new_hash.hash_second_key?(:p,:q)
  # =>"r"
要修改代码,请执行以下操作:

if myhash.has_second_key?('first-key','second-key') 
  ...
end
此方法将返回
nil
,在Ruby中为false,或者返回第二个键的值,在Ruby中为Truthy

显然,如果不想修改哈希类,就不必修改它。除了散列之外,您还可以将该方法作为参数<代码>有第二个密钥?(散列,k1,k2)
。然后称之为:

has_second_key?(myhash,'first-key','second-key')

我会指给你看最棒的

例如:

mash = Hashie::Mash.new

# Note: You used to be able to do : `mash.hello.world` and that would return `nil`
# However it seems that behavior has changed and now you need to use a `!` :

mash.hello!.world # => nil  # Note use of `!`


mash.hello!.world = 'Nice'  # Multi-level assignment!


mash.hello.world # => "Nice"
# or
mash.hello!.world # => "Nice"

不要对条件使用
关键字。使用
和&
错误,问题是
第二个\u键
我的\u散列中不存在。它是第二个散列中的一个键,与
my_hash
完全无关。您正在嵌套两个完全不同的散列对象。“present”是指不是
nil
或不是空的或
nil
?例如,如果它存在,但它是
'
或甚至
'
这被认为是“存在”还是没有?您可能想使用
。尝试(:某物)
方法:您可以使用
|
<代码>如果(myhash['first_key']|{})['second_key']
这是rails方法吗?那就试试
?是的,Rails方法。OP将问题标记为RoR。没问题,我不知道RoR。。呵呵:)除了移动它,我不知道该如何重构它。如果你提供更多的上下文,我可能会有所帮助。这是怎么回事
hsh={a:{c:1}}[:a,:d].inject(hsh,:[])#=>nil
@babai:这不会处理像
:a,:d,:e