Ruby: 如何创建嵌套的 key/value 关系
Ruby: How to create nested key/value relationship
我正在尝试创建一个函数来输出 JSON 的所有条目的键和值,如下所述,因此我可以使用它来发送类似于此的信息:
key = "id", value = 1
key = "mem/stat1", value = 10
key = "more_stats/extra_stats/stat7", value = 5
示例JSON:
my_json =
{
"id": 1,
"system_name": "System_1",
"mem" : {
"stat1" : 10,
"stat2" : 1056,
"stat3" : 10563,
},
"other_stats" : {
"stat4" : 1,
"stat5" : 2,
"stat6" : 3,
},
"more_stats" : {
"name" : "jdlfjsdlfjs",
"os" : "fjsalfjsl",
"error_count": 3
"extra_stats" : {
"stat7" : 5,
"stat8" : 6,
},
}
}
我从这个问题 (need help in getting nested ruby hash hierarchy) 中找到了一个很有帮助的答案,但即使进行了一些改动,它仍然无法正常工作:
def hashkeys(json, keys = [], result = [])
if json.is_a?(Hash)
json.each do |key, value|
hashkeys(value, keys + [key], result)
end
else
result << keys
end
result.join("/")
end
它 returns 将所有键作为一个字符串组合在一起,并没有像我希望的那样正确包含任何相应的值。
当前不需要的散列键输出:
id/system_name/mem/stat1/mem/stat2/...
理想情况下,我想要一些可以接受的东西 my_json
:
find_nested_key_value(my_json)
some logic loop involving key and value:
if more logic needed
another_logic_loop_for_more_nested_info
else
send_info(final_key, final_value)
end
end
end
所以如果 final_key = "mem/stat1"
然后 final_value = 10
,那么下一次迭代将是 final_key = "mem/stat2"
和 final_value = 1056
等等
我该如何实现?并且正在使用像 hashkeys
这样的函数是实现此目的的最佳方法
这是一个递归方法,它将创建一个 "flattened hash",一个没有嵌套的散列,其中键是由斜杠分隔的嵌套键。
def flatten_hash(hash, result = {}, prefix = nil)
hash.each do |k,v|
if v.is_a? Hash
flatten_hash(v, result, [prefix, k].compact.join('/'))
else
result[[prefix, k].compact.join('/')] = v
end
end
result
end
my_hash = {'id': 1, 'system_name': 'Sysem_1', 'mem': {'stat1': 10, 'stat2': 1056, 'stat3': 10563}}
flatten_hash(my_hash)
=> {"id"=>1, "system_name"=>"Sysem_1", "mem/stat1"=>10, "mem/stat2"=>1056, "mem/stat3"=>10563}
def key_path_value(key_string, my_json)
value = nil
key_array = key_string.split("/")
return value if key_array.empty?
return my_json[key_array.last] if key_array.length == 1
value = my_json[key_array.first.to_sym]
key_array = key_array.drop(1)
key_array.each do |key|
break unless value.is_a? Hash
value = value[key.to_sym]
end
return value
end
我正在尝试创建一个函数来输出 JSON 的所有条目的键和值,如下所述,因此我可以使用它来发送类似于此的信息:
key = "id", value = 1
key = "mem/stat1", value = 10
key = "more_stats/extra_stats/stat7", value = 5
示例JSON:
my_json =
{
"id": 1,
"system_name": "System_1",
"mem" : {
"stat1" : 10,
"stat2" : 1056,
"stat3" : 10563,
},
"other_stats" : {
"stat4" : 1,
"stat5" : 2,
"stat6" : 3,
},
"more_stats" : {
"name" : "jdlfjsdlfjs",
"os" : "fjsalfjsl",
"error_count": 3
"extra_stats" : {
"stat7" : 5,
"stat8" : 6,
},
}
}
我从这个问题 (need help in getting nested ruby hash hierarchy) 中找到了一个很有帮助的答案,但即使进行了一些改动,它仍然无法正常工作:
def hashkeys(json, keys = [], result = [])
if json.is_a?(Hash)
json.each do |key, value|
hashkeys(value, keys + [key], result)
end
else
result << keys
end
result.join("/")
end
它 returns 将所有键作为一个字符串组合在一起,并没有像我希望的那样正确包含任何相应的值。
当前不需要的散列键输出:
id/system_name/mem/stat1/mem/stat2/...
理想情况下,我想要一些可以接受的东西 my_json
:
find_nested_key_value(my_json)
some logic loop involving key and value:
if more logic needed
another_logic_loop_for_more_nested_info
else
send_info(final_key, final_value)
end
end
end
所以如果 final_key = "mem/stat1"
然后 final_value = 10
,那么下一次迭代将是 final_key = "mem/stat2"
和 final_value = 1056
等等
我该如何实现?并且正在使用像 hashkeys
这样的函数是实现此目的的最佳方法
这是一个递归方法,它将创建一个 "flattened hash",一个没有嵌套的散列,其中键是由斜杠分隔的嵌套键。
def flatten_hash(hash, result = {}, prefix = nil)
hash.each do |k,v|
if v.is_a? Hash
flatten_hash(v, result, [prefix, k].compact.join('/'))
else
result[[prefix, k].compact.join('/')] = v
end
end
result
end
my_hash = {'id': 1, 'system_name': 'Sysem_1', 'mem': {'stat1': 10, 'stat2': 1056, 'stat3': 10563}}
flatten_hash(my_hash)
=> {"id"=>1, "system_name"=>"Sysem_1", "mem/stat1"=>10, "mem/stat2"=>1056, "mem/stat3"=>10563}
def key_path_value(key_string, my_json)
value = nil
key_array = key_string.split("/")
return value if key_array.empty?
return my_json[key_array.last] if key_array.length == 1
value = my_json[key_array.first.to_sym]
key_array = key_array.drop(1)
key_array.each do |key|
break unless value.is_a? Hash
value = value[key.to_sym]
end
return value
end