¿Cómo haría para eliminar todos los elementos vacíos (elementos de lista vacíos) de un archivo Hash o YAML anidado?
ruby-on-rails
ruby
hash
yaml
Brian Jordan
fuente
fuente

Hash#delete_ifes una operación destructiva, mientras que loscompactmétodos no modifican el objeto. Puedes usarHash#reject. O llame al métodoHash#compact!.compactycompact!viene estándar en Ruby => 2.4.0, y Rails => 4.1. Sin embargo, no son recursivos.HashWithIndifferentAccess... Verifique mi versión en stackoverflow.com/a/53958201/1519240¡Rails 4.1 agregó Hash # compact y Hash # compact! como extensiones centrales de la
Hashclase de Ruby . Puedes usarlos así:Atención: esta implementación no es recursiva. Como curiosidad, lo implementaron usando en
#selectlugar de#delete_ifpor razones de rendimiento. Ver aquí para el punto de referencia .En caso de que desee realizar un backport a su aplicación Rails 3:
fuente
Use hsh.delete_if . En su caso específico, algo como:
hsh.delete_if { |k, v| v.empty? }fuente
proc = Proc.new { |k, v| v.kind_of?(Hash) ? (v.delete_if(&l); nil) : v.empty? }; hsh.delete_if(&proc)NoMethodErrorif sives nulo.Si está utilizando Ruby 2.4+, puede llamar
compactycompact!https://ruby-doc.org/core-2.4.0/Hash.html#method-i-compact-21
fuente
Este también eliminaría los hashes vacíos:
fuente
swoop = Proc.new { |k, v| v.delete_if(&swoop) if v.kind_of?(Hash); v.blank? }Puede usar Hash # rechazar para eliminar pares de clave / valor vacíos de un ruby Hash.
fuente
.empty?arroja un error para los números, por lo que puede usar.blank?enRailsfunciona tanto para hashes como para arrays
PD basado en la respuesta de alguien, no puedo encontrar
uso -
Helpers::RecursiveCompact.recursive_compact(something)fuente
Sé que este hilo es un poco viejo, pero se me ocurrió una solución mejor que admite hashes multidimensionales. Utiliza delete_if? excepto que es multidimensional y limpia cualquier cosa con un valor vacío de forma predeterminada y si se pasa un bloque, se pasa a través de sus hijos.
fuente
Hice un método deep_compact para esto que filtra recursivamente registros nulos (y opcionalmente, registros en blanco también):
fuente
Ruby
Hash#compact,Hash#compact!yHash#delete_if!no funcionan en anidadosnil,empty?y / oblank?valores. Tenga en cuenta que los dos últimos métodos son destructivos, y que todosnil,"",false,[]y{}los valores se cuentan comoblank?.Hash#compactyHash#compact!solo están disponibles en Rails, o Ruby versión 2.4.0 y superior.Aquí hay una solución no destructiva que elimina todas las matrices, hashes, cadenas y
nilvalores vacíos , manteniendo todos losfalsevalores:(
blank?se puede reemplazar connil?oempty?según sea necesario)Una versión destructiva:
O, si desea agregar ambas versiones como métodos de instancia en la
Hashclase:Otras opciones:
v.blank? && v != falseconv.nil? || v == ""para eliminar estrictamente cadenas ynilvalores vacíosv.blank? && v != falseconv.nil?para eliminar estrictamente losnilvaloresEDITADO el 15/03/2017 para mantener
falsevalores y presentar otras opcionesfuente
nuestra versión: también limpia las cadenas vacías y los valores nulos
fuente
En Simple one liner para eliminar valores nulos en Hash,
fuente
blank?va por cuerdas vacías tambiénSe podría hacer con la biblioteca de facetas (características que faltan de la biblioteca estándar), así:
Funciona con cualquier Enumerable (incluyendo Array, Hash).
Mira cómo se implementa el método recursivamente .
fuente
Creo que sería mejor usar un método auto recursivo. De esa manera va tan profundo como sea necesario. Esto eliminará el par de valores clave si el valor es nulo o un hash vacío.
Luego, usarlo se verá así:
Para mantener hashes vacíos, puede simplificar esto.
fuente
fuente
Intenta esto para eliminar nada
fuente
hash.compact!La versión recursiva de https://stackoverflow.com/a/14773555/1519240 funciona, pero no con
HashWithIndifferentAccessu otras clases que son una especie de Hash.Aquí está la versión que estoy usando:
kind_of?(Hash)aceptará más clases que son como un Hash.También puede reemplazar
inject({})porinject(HashWithIndifferentAccess.new)si desea acceder al nuevo hash utilizando tanto el símbolo como la cadena.fuente
Aquí hay algo que tengo:
fuente
Eliminación profunda de valores nulos de un hash.
fuente
Si está utilizando
Rails(o de forma independienteActiveSupport), a partir de la versión6.1, hay uncompact_blankmétodo que elimina losblankvalores de los hashes.Se utiliza
Object#blank?debajo del capó para determinar si un elemento está en blanco.Aquí hay un enlace a los documentos y un enlace al PR relativo .
Una variante destructiva también está disponible. Ver
Hash#compact_blank!.Si necesita eliminar solo
nilvalores,por favor, considere usar los métodos
Hash#compacty la compilación de RubyHash#compact!.fuente