Wie würde ich vorgehen, um alle leeren Elemente (leere Listenelemente) aus einer verschachtelten Hash- oder YAML-Datei zu entfernen?
ruby-on-rails
ruby
hash
yaml
Brian Jordan
quelle
quelle
Hash#delete_if
handelt sich um eine destruktive Operation, währendcompact
Methoden das Objekt nicht ändern. Sie können verwendenHash#reject
. Oder rufen Sie die Methode aufHash#compact!
.compact
undcompact!
kommen standardmäßig in Ruby => 2.4.0 und Rails => 4.1. Sie sind jedoch nicht rekursiv.HashWithIndifferentAccess
. Überprüfen Sie meine Version unter stackoverflow.com/a/53958201/1519240Rails 4.1 hat Hash # compact und Hash # compact hinzugefügt ! als Kernerweiterung von Rubys
Hash
Klasse. Sie können sie folgendermaßen verwenden:Heads up: Diese Implementierung ist nicht rekursiv. Aus Neugier haben sie es
#select
anstelle von#delete_if
aus Leistungsgründen implementiert . Siehe hier für den Benchmark .Falls Sie es auf Ihre Rails 3-App zurückportieren möchten:
quelle
Verwenden Sie hsh.delete_if . In Ihrem speziellen Fall so etwas wie:
hsh.delete_if { |k, v| v.empty? }
quelle
proc = Proc.new { |k, v| v.kind_of?(Hash) ? (v.delete_if(&l); nil) : v.empty? }; hsh.delete_if(&proc)
NoMethodError
Wennv
ist Null.Wenn Sie Ruby 2.4+ verwenden, können Sie
compact
und anrufencompact!
https://ruby-doc.org/core-2.4.0/Hash.html#method-i-compact-21
quelle
Dieser würde auch leere Hashes löschen:
quelle
swoop = Proc.new { |k, v| v.delete_if(&swoop) if v.kind_of?(Hash); v.blank? }
Mit Hash # ablehnen können Sie leere Schlüssel / Wert-Paare aus einem Ruby-Hash entfernen.
quelle
.empty?
Ihrer Information: Wirft Fehler für Zahlen, so dass Sie.blank?
inRails
funktioniert sowohl für Hashes als auch für Arrays
PS basierend auf jemandes Antwort, kann nicht finden
Verwendung -
Helpers::RecursiveCompact.recursive_compact(something)
quelle
Ich weiß, dass dieser Thread etwas alt ist, aber ich habe eine bessere Lösung gefunden, die mehrdimensionale Hashes unterstützt. Es verwendet delete_if? außer es ist mehrdimensional und bereinigt standardmäßig alles mit einem leeren Wert. Wenn ein Block übergeben wird, wird er über seine untergeordneten Elemente weitergegeben.
quelle
Ich habe dafür eine deep_compact-Methode erstellt, die rekursiv keine Datensätze herausfiltert (und optional auch leere Datensätze):
quelle
Ruby
Hash#compact
,Hash#compact!
undHash#delete_if!
nicht die Arbeit an verschachteltennil
,empty?
und / oderblank?
Werte. Man beachte , dass die beiden letztgenannten Methoden destruktiv sind, und dass allenil
,""
,false
,[]
und{}
Werte werden gezählt alsblank?
.Hash#compact
undHash#compact!
sind nur in Rails oder Ruby Version 2.4.0 und höher verfügbar.Hier ist eine zerstörungsfreie Lösung, die alle leeren Arrays, Hashes, Strings und
nil
Werte entfernt und dabei allefalse
Werte beibehält:(
blank?
kann durchnil?
oderempty?
nach Bedarf ersetzt werden.)Eine destruktive Version:
Oder wenn Sie beide Versionen als Instanzmethoden zur
Hash
Klasse hinzufügen möchten :Andere Optionen:
v.blank? && v != false
durchv.nil? || v == ""
, um leere Zeichenfolgen und strikt zu entfernennil
Wertev.blank? && v != false
durchv.nil?
, umnil
Werte strikt zu entfernenEDITED 2017/03/15, um
false
Werte zu halten und andere Optionen zu präsentierenquelle
Unsere Version: Es werden auch die leeren Zeichenfolgen und Nullwerte bereinigt
quelle
In Simple One Liner zum Löschen von Nullwerten in Hash,
quelle
blank?
geht auch für leere SaitenKönnte mit Facettenbibliothek (eine fehlende Funktion aus der Standardbibliothek) wie folgt gemacht werden:
Funktioniert mit allen Enumerable (einschließlich Array, Hash).
Schauen Sie, wie die rekursive Methode implementiert ist.
quelle
Ich glaube, es wäre am besten, eine selbstrekursive Methode zu verwenden. Auf diese Weise geht es so tief wie nötig. Dadurch wird das Schlüsselwertpaar gelöscht, wenn der Wert Null oder ein leerer Hash ist.
Dann sieht es folgendermaßen aus:
Um leere Hashes zu behalten, können Sie dies vereinfachen.
quelle
quelle
Versuchen Sie dies, um Null zu entfernen
quelle
hash.compact!
Die rekursive Version von https://stackoverflow.com/a/14773555/1519240 funktioniert, jedoch nicht mit
HashWithIndifferentAccess
oder anderen Klassen, die eine Art Hash sind.Hier ist die Version, die ich benutze:
kind_of?(Hash)
akzeptiert mehr Klassen, die wie ein Hash sind.Sie können auch ersetzen
inject({})
durch ,inject(HashWithIndifferentAccess.new)
wenn Sie den neuen Hash unter Verwendung von sowohl Symbol und String zugreifen möchten.quelle
Hier ist etwas, was ich habe:
quelle
Tiefes Löschen von Nullwerten aus einem Hash.
quelle
Wenn Sie ab Version
Rails
(oder StandaloneActiveSupport
) verwenden,6.1
gibt es einecompact_blank
Methode, mit derblank
Werte aus Hashes entfernt werden.Es wird
Object#blank?
unter der Haube verwendet, um festzustellen, ob ein Artikel leer ist.Hier ist ein Link zu den Dokumenten und ein Link zur relativen PR .
Eine destruktive Variante ist ebenfalls erhältlich. Siehe
Hash#compact_blank!
.Wenn Sie nur
nil
Werte entfernen müssen ,Bitte erwägen Sie die Verwendung von Ruby Build-In
Hash#compact
undHash#compact!
Methoden.quelle