Есть ли способ сделать глубокое удаление, используя рубиновый хэш-гем? - PullRequest
0 голосов
/ 21 февраля 2019

Таким образом, в hashie есть метод deep_find_all, который можно использовать для поиска всех ключей во вложенном хэше, но есть ли способ выполнить глубокое удаление или глубокое обнаружение, которое возвращает ключи таким образом, что они могут быть удалены.

Я вижу, где я могу преобразовать хэш в mashie и выполнить удаление, но, похоже, он не выходит за пределы верхнего уровня.

Я пытаюсь удалить все ключииз JSON, которые содержат метку времени, чтобы я мог сравнить результаты двух разных хостов.Я реализовал способ сделать это, но это кажется немного неуклюжим, и глубокое удаление было бы просто билетом.

Спасибо, Крейг

1 Ответ

0 голосов
/ 21 февраля 2019

Вы можете создать общий метод 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...