Ruby's Hash#compact
, Hash#compact!
и Hash#delete_if!
не работают с вложенными значениями nil
, empty?
и / или blank?
.Обратите внимание, что последние два метода являются разрушительными, и что все значения nil
, ""
, false
, []
и {}
считаются blank?
.
Hash#compact
и Hash#compact!
доступны только в Rails или Ruby версии 2.4.0 и выше.
Вот неразрушающее решение, которое удаляет все пустые массивы, хэши, строки и значения nil
, сохраняя при этом все false
значения:
(blank?
можно заменить на nil?
или empty?
при необходимости.)
def remove_blank_values(hash)
hash.each_with_object({}) do |(k, v), new_hash|
unless v.blank? && v != false
v.is_a?(Hash) ? new_hash[k] = remove_blank_values(v) : new_hash[k] = v
end
end
end
Деструктивная версия:
def remove_blank_values!(hash)
hash.each do |k, v|
if v.blank? && v != false
hash.delete(k)
elsif v.is_a?(Hash)
hash[k] = remove_blank_values!(v)
end
end
end
Или, если вы хотите добавить обе версии в качестве методов экземпляра для класса Hash
:
class Hash
def remove_blank_values
self.each_with_object({}) do |(k, v), new_hash|
unless v.blank? && v != false
v.is_a?(Hash) ? new_hash[k] = v.remove_blank_values : new_hash[k] = v
end
end
end
def remove_blank_values!
self.each_pair do |k, v|
if v.blank? && v != false
self.delete(k)
elsif v.is_a?(Hash)
v.remove_blank_values!
end
end
end
end
Другие параметры:
- Заменить
v.blank? && v != false
на v.nil? || v == ""
для строгого удаленияпустые строки и nil
значения - Заменить
v.blank? && v != false
на v.nil?
для строгого удаления nil
значений - И т.д.
РЕДАКТИРОВАНИЕ 2017/03 /15, чтобы сохранить false
значения и представить другие параметры