¿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_if
es una operación destructiva, mientras que loscompact
métodos no modifican el objeto. Puedes usarHash#reject
. O llame al métodoHash#compact!
.compact
ycompact!
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
Hash
clase de Ruby . Puedes usarlos así:Atención: esta implementación no es recursiva. Como curiosidad, lo implementaron usando en
#select
lugar de#delete_if
por 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)
NoMethodError
if siv
es nulo.Si está utilizando Ruby 2.4+, puede llamar
compact
ycompact!
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?
enRails
funciona 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#compact
yHash#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
nil
valores vacíos , manteniendo todos losfalse
valores:(
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
Hash
clase:Otras opciones:
v.blank? && v != false
conv.nil? || v == ""
para eliminar estrictamente cadenas ynil
valores vacíosv.blank? && v != false
conv.nil?
para eliminar estrictamente losnil
valoresEDITADO el 15/03/2017 para mantener
false
valores 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
HashWithIndifferentAccess
u 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_blank
método que elimina losblank
valores 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
nil
valores,por favor, considere usar los métodos
Hash#compact
y la compilación de RubyHash#compact!
.fuente