如果我有这样的多嵌套哈希值
{
"Monday"=>{
"North"=>{
"Group 1"=>[
{:name=>"Event A", :type=>"Private"},
{:name=>"Event B", :type=>"Public"},
]
},
"South"=>{
"Group 1"=>[
{:name=>"Event c", :type=>"Private"},
{:name=>"Event D", :type=>"Public"},
{:name=>"Event E", :type=>"Private"},
]
}
},
"Tuesday"=>{
"North"=>{
"Group 1"=>[
{:name=>"Event F", :type=>"Private"},
{:name=>"Event G", :type=>"Public"},
]
},
"South"=>{
"Group 1"=>[
{:name=>"Event H", :type=>"Private"},
]
}
}
}
我希望能够在哈希中搜索所有type
等于Private
的事件
在不完全知道哈希中键的值的情况下,我该怎么做?
答案 0 :(得分:1)
如果使用 gem 是一种选择,则存在iteraptor
,这显然是关于迭代深层嵌套的结构。
假设您的原始哈希名为hash
,我们开始:
hash.iteraptor.
each(full_parent: true, yield_all: true).
with_object({}) do |(parent, (k, v)), acc|
(acc[parent[0...-1]] ||= []) << k if
parent.last.is_a?(Integer) && v.nil? && k.is_a?(Hash) && k[:type] == "Private"
end
结果:
#⇒ {["Monday", "North", "Group 1"] =>
# [{:name=>"Event A", :type=>"Private"}],
# ["Monday", "South", "Group 1"] =>
# [{:name=>"Event c", :type=>"Private"},
# {:name=>"Event E", :type=>"Private"}],
# ["Tuesday", "North", "Group 1"] =>
# [{:name=>"Event F", :type=>"Private"}],
# ["Tuesday", "South", "Group 1"] =>
# [{:name=>"Event H", :type=>"Private"}]}
答案 1 :(得分:1)
在递归解决此问题时,我做了三个假设:
:type
是唯一已知的密钥; :type
,则它恰好包含另一个密钥。
def get_em(obj)
arr = []
case obj
when Hash
obj.values.each do |v|
case v
when "Private"
arr += obj.values-[v]
when Hash, Array
arr += get_em(v)
end
end
when Array
obj.each { |e| arr += get_em(e) if Hash === e || Array === e }
end
arr
end
如果h
是示例中给出的哈希,
get_em(h)
#=> ["Event A", "Event C", "Event E", "Event F", "Event H"]
注意Hash === e
等同于e.is_a?(Hash)
。
答案 2 :(得分:0)
尝试此递归:
def hash_match(the_hash)
found=false
the_hash.each do |key, value|
if value.is_a?(Hash)
if hash_match(value)
if value.has_key :name
puts value[:name]
end
end
elsif value.is_a?(Array)
value.each do |element|
if element.is_a?(Hash)
if hash_match(element)
if element.has_key? :name
puts element[:name]
end
end
end
end
else
if key==:type && value=="Private"
found=true
end
end
end
return found
end
然后只需致电hash_match(your_hash)