Como eu removeria todos os elementos vazios (itens de lista vazios) de um arquivo Hash ou YAML aninhado?
ruby-on-rails
ruby
hash
yaml
Brian Jordan
fonte
fonte
Hash#delete_if
é uma operação destrutiva, enquanto oscompact
métodos não modificam o objeto. Você pode usarHash#reject
. Ou chamar o métodoHash#compact!
.compact
ecompact!
é padrão no Ruby => 2.4.0 e Rails => 4.1. Eles não são recursivos.HashWithIndifferentAccess
.. Verifique minha versão em stackoverflow.com/a/53958201/1519240O Rails 4.1 adicionou o Hash # compact e o Hash # compact! como extensões principais da
Hash
classe Ruby . Você pode usá-los assim:Atenção: essa implementação não é recursiva. Como curiosidade, eles o implementaram usando em
#select
vez de#delete_if
por razões de desempenho. Veja aqui o benchmark .Caso você queira fazer o backport para seu aplicativo Rails 3:
fonte
Use hsh.delete_if . No seu caso específico, algo como:
hsh.delete_if { |k, v| v.empty? }
fonte
proc = Proc.new { |k, v| v.kind_of?(Hash) ? (v.delete_if(&l); nil) : v.empty? }; hsh.delete_if(&proc)
NoMethodError
ifv
é nulo.Se você usa o Ruby 2.4+, pode ligar
compact
ecompact!
https://ruby-doc.org/core-2.4.0/Hash.html#method-i-compact-21
fonte
Este também excluiria hashes vazios:
fonte
swoop = Proc.new { |k, v| v.delete_if(&swoop) if v.kind_of?(Hash); v.blank? }
Você pode usar o Hash # rejeitar para remover pares de chave / valor vazios de um Hash ruby.
fonte
.empty?
lança erro para números, para que você possa usar.blank?
emRails
funciona para hashes e matrizes
PS com base na resposta de alguém, não consigo encontrar
uso -
Helpers::RecursiveCompact.recursive_compact(something)
fonte
Eu sei que esta discussão é um pouco antiga, mas eu vim com uma solução melhor que suporta hashes multidimensionais. Ele usa delete_if? exceto sua multidimensional e limpa qualquer coisa com um valor vazio por padrão e se um bloco é passado, ele é passado através de seus filhos.
fonte
Eu criei um método deep_compact para isso que filtra recursivamente os registros nulos (e, opcionalmente, os registros em branco):
fonte
Ruby
Hash#compact
,Hash#compact!
eHash#delete_if!
não funcionam em nestednil
,empty?
e / oublank?
valores. Note-se que os dois últimos métodos são destrutivos, e que todasnil
,""
,false
,[]
e{}
os valores são contados quantoblank?
.Hash#compact
eHash#compact!
estão disponíveis apenas no Rails ou Ruby versão 2.4.0 e superior.Aqui está uma solução não destrutiva que remove todas as matrizes, hashes, strings e
nil
valores vazios , mantendo todos osfalse
valores:(
blank?
pode ser substituído pornil?
ouempty?
conforme necessário.)Uma versão destrutiva:
Ou, se você deseja adicionar ambas as versões como métodos de instância na
Hash
classe:Outras opções:
v.blank? && v != false
porv.nil? || v == ""
para remover estritamente as cordas vazias enil
valoresv.blank? && v != false
porv.nil?
para remover estritamente osnil
valoresEDITADO 2017/03/15 para manter
false
valores e apresentar outras opçõesfonte
nossa versão: também limpa as strings vazias e os valores nulos
fonte
Em Um liner simples para excluir valores nulos no Hash,
fonte
blank?
vai para cadeias vazias bemPode ser feito com a biblioteca de facetas (faltam recursos da biblioteca padrão), assim:
Funciona com qualquer enumerável (incluindo matriz, hash).
Veja como o método recursivamente é implementado.
fonte
Eu acredito que seria melhor usar um método auto recursivo. Dessa forma, vai tão fundo quanto é necessário. Isso excluirá o par de valores-chave se o valor for nulo ou um Hash vazio.
Em seguida, usá-lo ficará assim:
Para manter hashes vazios, você pode simplificar isso para.
fonte
fonte
Tente fazer isso para remover nada
fonte
hash.compact!
A versão recursiva de https://stackoverflow.com/a/14773555/1519240 funciona, mas não com
HashWithIndifferentAccess
ou outras classes que são do tipo Hash ..Aqui está a versão que estou usando:
kind_of?(Hash)
aceitará mais classes que são como um Hash.Você também pode substituir
inject({})
porinject(HashWithIndifferentAccess.new)
se desejar acessar o novo hash usando o símbolo e a sequência.fonte
Aqui está algo que eu tenho:
fonte
Exclusão profunda de zero valores de um hash.
fonte
Se você estiver usando
Rails
(ou autônomoActiveSupport
), a partir da versão6.1
, existe umcompact_blank
método que remove osblank
valores dos hashes.Ele é usado
Object#blank?
sob o capô para determinar se um item está em branco.Aqui está um link para os documentos e um link para o PR relativo .
Uma variante destrutiva também está disponível. Veja
Hash#compact_blank!
.Se você precisar remover apenas
nil
valores,por favor, considere o uso de métodos
Hash#compact
e build de RubyHash#compact!
.fonte