我有一个以下列格式返回json的Web服务:
[
{
"key": "linux.ubuntu.ip",
"value": "10.10.10.10"
},
{
"key": "linux.ubuntu.hostname",
"value": "stageubuntu"
}
]
我有一个ruby代码,它调用这个服务并获取json。在此代码的深处,有configure
类型的变量Hashie::Mash
。
我想实现这个目标:
configure.linux.ubuntu.ip = 10.10.10.10 [Hashie::Mash]
configure.linux.ubuntu.hostname = stageubuntu [Hashie::Mash]
有人能告诉我是否有可能实现这个目标(w.r.t到我有的json输出)?如果是这样,最好的方法是什么?
答案 0 :(得分:0)
要将JSON字符串获取到Hashie::Mash
对象,您只需执行以下操作:
require 'json'
require 'hashie'
json_str = '{ "foo": "bar" }'
ruby_hash = JSON.parse(json_str)
Hashie::Mash.new(ruby_hash)
对于这个特定问题,虽然不理想(但我们都有独特的用例),但您需要解析为数组,然后将“键”提取到深度未知的嵌套Hashie :: Mash对象中。
require 'json'
require 'hashie'
json_str = <<-JSON
[
{
"key": "linux.ubuntu.ip",
"value": "10.10.10.10"
},
{
"key": "linux.ubuntu.hostname",
"value": "stageubuntu"
}
]
JSON
parsed_arr = JSON.parse(json_str)
#=> [{"key"=>"linux.ubuntu.ip", "value"=>"10.10.10.10"}, {"key"=>"linux.ubuntu.hostname", "value"=>"stageubuntu"}]
configure = parsed_arr.map do |parsed_hash|
method_chain = parsed_hash['key'].split('.')
init_value = Hashie::Mash.new(method_chain.pop => parsed_hash['value'])
method_chain.reverse.inject(init_value) do |ret_value, method_name|
Hashie::Mash.new(method_name => ret_value)
end
end.inject(:merge) # <-- hashie is allows you to perform a deep merge into a single object here.
# you can now do
configure.linux.ubuntu.ip = 10.10.10.10 [Hashie::Mash]
#=> "10.10.10.10"
configure.linux.ubuntu.hostname
#=> "stageubuntu"