我有以下内容:
data_spec['data'] = "some.awesome.values"
data_path = ""
data_spec['data'].split('.').each do |level|
data_path = "#{data_path}['#{level}']"
end
data = "site.data#{data_path}"
此时,data
等于字符串:"site.data['some']['awesome']['values']"
我需要帮助的是使用字符串来获取值:site.data['some']['awesome']['values']
site.data
具有以下值:
{
"some" => {
"awesome" => {
"values" => [
{
"things" => "Stuff",
"stuff" => "Things",
},
{
"more_things" => "More Stuff",
"more_stuff" => "More Things",
}
]
}
}
}
非常感谢任何帮助。谢谢!
答案 0 :(得分:4)
如果您使用的是ruby 2.3.0(这很棒且我甚至不知道存在),您可以像tadman建议的那样使用site.data.dig('some', 'awesome', values')
。这可能是您的最佳选择。但如果您真的想自己编写代码,请阅读以下内容。
你走在正确的轨道上,最好的方法是:
data_spec['data'] = "some.awesome.values"
data = nil
data_spec['data'].split('.').each do |level|
if data.nil?
data = site.data[level]
else
data = data[level]
end
end
为了理解为什么这首先有用,你需要理解site.data['some']['awesome']['values']
与说法相同:首先得到some
然后在得到awesome
里面然后得到values
。所以我们的第一步是检索some
。由于我们没有第一级,但我们从site.data
获取并将其保存到变量data
。一旦我们掌握了数据,我们就可以从数据中获取每个级别并将其保存到数据中,从而使我们能够更深入地了解哈希值。
因此,使用您的示例data
最初会如下所示:
{"awesome" => {
"values" => [
{
"things" => "Stuff",
"stuff" => "Things",
},
{
"more_things" => "More Stuff",
"more_stuff" => "More Things",
}
]
}
}
然后这个:
{"values" => [
{
"things" => "Stuff",
"stuff" => "Things",
},
{
"more_things" => "More Stuff",
"more_stuff" => "More Things",
}
]
}
最后输出如下:
[
{
"things" => "Stuff",
"stuff" => "Things",
},
{
"more_things" => "More Stuff",
"more_stuff" => "More Things",
}
]
答案 1 :(得分:4)
如果您收到类似'x.y.z'
的字符串并需要导航嵌套哈希,Ruby 2.3.0包含dig
方法:
spec = "some.awesome.values"
data = {
"some" => {
"awesome" => {
"values" => [
'a','b','c'
]
}
}
}
data.dig(*spec.split('.'))
# => ["a", "b", "c"]
如果您没有Ruby 2.3.0并且升级不是一个选项,您可以暂时修补它:
class Hash
def dig(*path)
path.inject(self) do |location, key|
location.respond_to?(:keys) ? location[key] : nil
end
end
end
答案 2 :(得分:0)
我写了一些确实如此的东西。随意从中获取任何有价值的信息或窃取它! :)
查看单元测试以了解如何使用它:
有一个返回lambda的accessor
方法。由于可以使用[]
运算符(方法,实际上)调用lambdas,因此可以获得这样的lambda并访问任意数量的级别:
accessor['hostname.ip_addresses.0']
或者,在您的情况下:
require 'trick_bag'
accessor = TrickBag::CollectionsAccess.accessor(site.data)
do_something_with(accessor['some.awesome.values'])
答案 3 :(得分:-2)
您正在寻找的东西通常被低估并且有充分的理由。但是你去了 - 它被称为eval
:
binding.eval data