Domanda

La creazione di hash di hash in Ruby consente di cercare comodamente due (o più) dimensioni. Tuttavia, quando si inserisce si deve sempre verificare se il primo indice esiste già nell'hash. Ad esempio:

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

Sarebbe preferibile fare quanto segue quando il nuovo hash viene creato automaticamente:

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

Allo stesso modo, quando si cerca un valore in cui il primo indice non esiste già, sarebbe preferibile restituire zero anziché ricevere un metodo indefinito per l'errore "[]".

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

Si potrebbe creare una classe wrapper Hash che ha questo comportamento, ma esiste già un idioma Ruby per portare a termine questo compito?

È stato utile?

Soluzione

Puoi passare il Hash.new funziona un blocco che viene eseguito per produrre un valore predefinito nel caso in cui il valore richiesto non esista ancora:

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

Naturalmente, questo può essere fatto in modo ricorsivo.

/ EDIT: Wow, c'è un articolo rispondendo proprio a questa domanda.

Per completezza, ecco la soluzione dell'articolo per hash di profondità arbitrari:

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

I crediti vanno nel Kent da Rumore dei dati .

Altri suggerimenti

L'autovivificazione, come viene chiamata, è sia una benedizione che una maledizione. Il problema può essere che se guardi " ad un valore prima che sia definito, sei bloccato con questo hash vuoto nello slot e dovrai eliminarlo in seguito.

Se non ti dispiace un po 'di anarchia, puoi sempre semplicemente inceppare in dichiarazioni di stile or-equal che ti permetteranno di costruire la struttura prevista mentre la interroghi:

((h ||= { })['w'] ||= { })['z']
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top