Frage

Hashes von Hashes in Ruby Erstellen ermöglicht eine komfortable zwei (oder mehr) dimensionale Lookups. man beim Einsetzen muss jedoch immer prüfen, ob der erste Index existiert bereits in der Hash. Zum Beispiel:

h = Hash.new
h['x'] = Hash.new if not h.key?('x')
h['x']['y'] = value_to_insert

Es wäre besser, die folgenden zu tun, wo der neue Hash automatisch erstellt wird:

h = Hash.new
h['x']['y'] = value_to_insert

Wenn in ähnlicher Weise einen Wert suchen, wo der erste Index nicht bereits vorhanden ist, wäre es besser, wenn sie gleich Null eher zurückgeführt wird als eine nicht definierte Methode Empfang für ‚[]‘ Fehler.

looked_up_value = h['w']['z']

Man könnte eine Hash-Wrapper-Klasse erstellen, die dieses Verhalten hat, aber gibt es ein bestehendes ein Idiom Rubin für Erfüllung dieser Aufgabe?

War es hilfreich?

Lösung

können Sie übergeben die Hash.new einen Block fungieren, ist ausgeführt, um einen Standardwert, falls der abgefragte Wert existiert noch nicht zu erhalten:

h = Hash.new { |h, k| h[k] = Hash.new }

Natürlich kann dies rekursiv durchgeführt werden.

/ EDIT: Wow, gibt es Artikel diese Frage zu beantworten.

Aus Gründen der Vollständigkeit, hier ist die Lösung aus dem Artikel für beliebige Tiefe Hashes:

hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))

Credits gehen Kent von Datenrauschen .

Andere Tipps

Autovivification, wie es genannt wird, ist ein Segen und ein Fluch. Das Problem kann das sein, wenn Sie auf einem Wert „Look“, bevor sie definiert ist, können Sie mit diesem leeren Hash in dem Schlitz stecken, und Sie würden es später beschneiden müssen aus.

Wenn Sie nicht ein bisschen Anarchie ausmacht, kann man immer nur Marmelade in oder-gleich-Stylesheets, die Sie die erwartete Struktur konstruieren können, wie Sie es abfragen:

((h ||= { })['w'] ||= { })['z']
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top