如果值:
myhash['first_key']['second_key']
存在,然后我需要得到它。但'second_key'
中可能根本不存在my_hash
,如果不是,我也不希望该行引发异常。
现在我正在用一个丑陋的条件包装整件事情:
if myhash['first_key'].present? and myhash['first_key']['second_key'].present?
...
end
我确定必须有更简单的东西。
答案 0 :(得分:8)
您始终可以使用try
:
hsh.try(:[], 'first_key').try(:[], 'second_key')
仅供参考:如果您正在进行大量此类检查,您可能需要重构代码以避免这些情况。
答案 1 :(得分:4)
如有疑问,请写一个包装器:
h = {
first_key: {
second_key: 'test'
}
}
class Hash
def fetch_path(*parts)
parts.reduce(self) do |memo, key|
memo[key] if memo
end
end
end
h.fetch_path(:first_key, :second_key) # => "test"
h.fetch_path(:first_key, :third_key) # => nil
h.fetch_path(:first_key, :third_key, :fourth_key) # => nil
h.fetch_path(:foo, :third_key) # => nil
答案 2 :(得分:4)
尝试这种干净整洁的解决方案。哈希默认值:
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
答案 3 :(得分:1)
我会指向优秀的Hashie::Mash
一个例子:
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"
答案 4 :(得分:0)
您可以在处理哈希之前设置一些默认值。类似的东西:
myhash[:first_key] ||= {}
if myhash[:first_key][:second_key]
# do work
end
答案 5 :(得分:0)
为什么不为此定义方法?
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中为Falsey,或者将返回Ruby中Truthy的第二个键的值。
显然,如果您不想修改Hash类,则无需修改。您可以使用除哈希之外的方法作为参数。 has_second_key?(hash,k1,k2)
。然后将其称为:
has_second_key?(myhash,'first-key','second-key')