我正在尝试编写一个返回哈希键值的函数,当提供一个键数组时(如果键不存在则为'nil')。
考虑哈希:
my_hash = {
font_size: 10,
font_family: "Arial",
boo: {
name: 'blah'
}
}
方法的存根可能是:
def get_value(hash, array_of_keys)
...
end
原因是我可以访问哈希中可能实际不存在的不同键。因此,例如,我想要'等等',通常我会打电话给my_hash[:boo][:name]
,但它可能不存在或者可能非常深。我想要做的是拥有我的函数,我可以使用get_value(my_hash, [:boo, :name])
调用,以便我可以测试每个密钥是否存在(因此,如果它们中的任何一个不存在,我不会得到异常,并且它不会这个价值可能有多“深”。
在我的情况下,检查我需要的每个值的存在是不可行的(我可能需要测试10个连续键的存在)我只需要一个函数,我可以说我需要哪个值并获取值,如果它存在,如果不存在,则为nil(因此不会尝试检索异常)。
我试了一下,尝试使用递归函数'每次循环时弹出数组中的第一个元素,但我无法锻炼如何返回我的值。
def get_value(val, arr)
if arr.count > 1
arr.each do |a|
get_value val[a], arr.pop
end
else
val[a]
end
end
get_value s, [:boo, :name]
这是我的尝试(显然不起作用) - 任何人都可以帮我解决这个问题,或者有一个可能更优雅的替代解决方案吗?几点:
答案 0 :(得分:4)
[:font_size].inject(my_hash){|h, k| h.to_h[k]} #=> 10
[:boo, :name].inject(my_hash){|h, k| h.to_h[k]} #=> "blah"
[:boo, :foo].inject(my_hash){|h, k| h.to_h[k]} #=> nil
答案 1 :(得分:1)
class Hash
def get_value(array_of_keys)
return nil unless array_of_keys.is_a? Array
return nil if array_of_keys.empty?
return nil unless self.has_key? array_of_keys.first
if self[array_of_keys.first].is_a? Hash
self[array_of_keys.first].get_value(array_of_keys[1..-1])
else
self[array_of_keys.first]
end
end
end
my_hash = {
font_size: 10,
font_family: "Arial",
boo: {
name: 'blah'
} ,
radley: {
one: {
more: {
time: 'now'
}
}
}
}
p my_hash.get_value [:boo, :name]
p my_hash.get_value [:radley, :one, :more, :time]
p my_hash.get_value [:radley, :one, :other, :time]
我将该方法直接添加到Hash
类,以便您可以将其作为现有哈希值的实例方法(使其更好用)。
该方法获取数组,如果参数实际上不是数组,则返回nil,如果数组为空,则返回nil,如果Hash
不包含与数组的第一个元素匹配的键。
接下来,检查该密钥的值本身是否为Hash
。
如果是这样,请在Hash
上使用数组的其余部分调用此方法!
如果值不是哈希值,则返回该值。
答案 2 :(得分:1)
我使用递归来刺伤它:
def get_value(hash, keys_array)
key = keys_array.shift
if hash.has_key? key
if hash[key].is_a?(Hash) && keys_array.size >= 1
get_value(hash[key], keys_array)
else
hash[key]
end
else
nil
end
end
顺便说一句好问题:)