我喜欢这里显示的方法 - https://stackoverflow.com/a/9648410/1646893我希望在我的情况下使用它。 如果我们有这样的事情怎么办:
{"a"=>{"b"=>"111", "c"=>"9", "d"=>{"ff"=>{"uu"=>[{"q"=>"77", "r"=>{"w"=>"66"}, "j"=>{"@l"=>"44"}}, {"q"=>"78", "r"=>{"w"=>"67"}, "j"=>{"@l"=>"45"}}]}, "@e"=>"56"}, "@b1"=>"01", "@b2"=>"02", "@b3"=>"03"}}
当我尝试使用我们的方法时:
{["a", "b"]=>"111", ["a", "c"]=>"9", ["a", "d", "ff", "uu"]=>[{"q"=>"77", "r"=>{"w"=>"66"}, "j"=>{"@l"=>"44"}}, {"q"=>"78", "r"=>{"w"=>"67"}, "j"=>{"@l"=>"45"}}], ["a", "d", "@e"]=>"56", ["a", "@b1"]=>"01", ["a", "@b2"]=>"02", ["a", "@b3"]=>"03"}
结果是一个包含2个值的数组:
[{"q"=>"77", "r"=>{"w"=>"66"}, "j"=>{"@l"=>"44"}}, {"q"=>"78", "r"=>{"w"=>"66"}, "j"=>{"@l"=>"44"}}]
这就是我想要的:
["a", "d", "ff", "uu", "q0", "w0", "j0", "@l0"]=>"44"
等
也许我应该在使用flat_hash方法之前更改键名? 如果没有数组和键名包含结果,我该怎么做?
答案 0 :(得分:1)
这是我的答案,产生了我认为是你所要求的更好的输出。如果你绝对迫切地需要你所要求的输出,请说明,也许我会提供一个产生它的变体。
class Hash; def each_with_key; each{ |k,v| yield(v,k) }; end; end
class Array; def each_with_key; each.with_index{ |v,i| yield(v,i) }; end; end
def path_to_values(hash)
{}.tap do |result|
crawl = ->(o,chain=[]) do
o.each_with_key do |v,k|
path = chain + [k]
(v.is_a?(Hash) || v.is_a?(Array)) ? crawl[v,path] : result[path] = v
end
end
crawl[hash]
end
end
见过:
h = {
"a" => {
"b"=>"111", "c"=>"9",
"d"=>{
"ff"=>{
"uu"=>[
{ "q"=>"77",
"r"=>{"w"=>"66"},
"j"=>{"@l"=>"44"}},
{ "q"=>"78",
"r"=>{"w"=>"67"},
"j"=>{"@l"=>"45"}}
]
},
"@e"=>"56"
},
"@b1"=>"01", "@b2"=>"02", "@b3"=>"03"
}
}
require 'pp'
pp path_to_values(h)
#=> {["a", "b"]=>"111",
#=> ["a", "c"]=>"9",
#=> ["a", "d", "ff", "uu", 0, "q"]=>"77",
#=> ["a", "d", "ff", "uu", 0, "r", "w"]=>"66",
#=> ["a", "d", "ff", "uu", 0, "j", "@l"]=>"44",
#=> ["a", "d", "ff", "uu", 1, "q"]=>"78",
#=> ["a", "d", "ff", "uu", 1, "r", "w"]=>"67",
#=> ["a", "d", "ff", "uu", 1, "j", "@l"]=>"45",
#=> ["a", "d", "@e"]=>"56",
#=> ["a", "@b1"]=>"01",
#=> ["a", "@b2"]=>"02",
#=> ["a", "@b3"]=>"03"}