Вы можете создать общий метод ruby:
def hash_recurse(hash, &blk)
hash.each do |key, val|
blk.call(hash, key, val)
if val.is_a?(Hash)
hash_recurse(val, &blk)
end
end
end
Затем вы можете передать любой блок, включая один, для удаления:
hash = {
a: {
timestamp: 123,
key: "val1"
},
b: {
timestamp: 456,
foo: "val2"
}
}
hash_recurse(hash) do |_hash, key, val|
_hash.delete(key) if key == :timestamp
end
puts hash
# => {:a=>{:key=>"val1"}, :b=>{:foo=>"val2"}}
По сути, это то же самое, что и глубинаПервый поиск.Например, если вы хотите извлечь «пути» ко всем ключам в хэше и его подшахах, вы можете изменить его, чтобы сохранить запись о текущем пути:
def hash_recurse(hash, path=[], &blk)
hash.each do |key, val|
new_path = path + [key]
blk.call(hash, key, val, new_path)
if val.is_a?(Hash)
hash_recurse(val, new_path, &blk)
end
end
end
и получить путивот так:
paths = []
hash_recurse(hash) do |_hash, key, val, path|
paths << path
end
paths.each { |path| puts path.join(",") }
# =>
# a
# a,timestamp
# a,key
# b
# b,timestamp
# b,foo