如果你想避免在查找时迭代(我觉得没有必要),那么你需要平展要存储的哈希:
>我的目标是创建一个用哈希初始化的对象,然后查询这个对象以便从该哈希中获取值。为了更清楚起见,这里有一个粗略的例子来说明我的意思:
class HashHolder
def initialize(hash)
@hash = hash
end
def get_value(*args)
# What are my possibilities here?
end
end
holder = HashHolder.new({:a => { :b => { :c => "value" } } } )
holder.get_value(:a, :b, :c) # should return "value"
我知道我可以在参数列表中执行迭代,如下所示:
def get_value(*args)
value = @hash
args.each do |k|
value = value[k]
end
return value
end
但是,如果我打算经常使用这种方法,这将大大降低我的性能,而我只想访问哈希值。
对此有什么建议吗?
更新答案,因为自从被问到以来已经有一段时间了。
(在 Ruby 2.3.1 中测试)
你有这样的哈希值:
my_hash = {:a => { :b => { :c => "value" } } }
问题问道:
my_hash.get_value(:a, :b, :c) # should return "value"
答:使用"dig"而不是get_value,如下所示:
my_hash.dig(:a,:b,:c) # returns "value"
由于问题的标题具有误导性(它应该是这样的:如何在带有键数组的嵌套哈希中获取值),以下是实际提出的问题的答案:
通过键数组获取 ruby 哈希值
制备:
my_hash = {:a => 1, :b => 3, :d => 6}
my_array = [:a,:d]
答:
my_hash.values_at(*my_array) #returns [1,6]
def get_value(*args)
args.inject(@hash, &:fetch)
end
如果你想避免在查找时迭代(我觉得没有必要),那么你需要平展要存储的哈希:
class HashHolder
def initialize(hash)
while hash.values.any?{|v| v.kind_of?(Hash)}
hash.to_a.each{|k, v| if v.kind_of?(Hash); hash.delete(k).each{|kk, vv| hash[[*k, kk]] = vv} end}
end
@hash = hash
end
def get_value(*args)
@hash[args]
end
end
如果您知道哈希的结构始终采用该格式,您可以执行以下操作:
holder[:a][:b][:c]
。返回"值"。