into example create ruby idioms hash-of-hashes

example - Hashes of Hashes Idiom en Ruby?



ruby create hash (2)

La autovigilancia, como se llama, es a la vez una bendición y una maldición. El problema puede ser que si "miras" un valor antes de que se defina, estás atascado con este hash vacío en la ranura y tendrías que podarlo más tarde.

Si no te importa un poco la anarquía, siempre puedes crear declaraciones de estilo equivalentes que te permitirán construir la estructura esperada mientras la consultas:

((h ||= { })[''w''] ||= { })[''z'']

La creación de hashes de hashes en Ruby permite realizar dos búsquedas (o más) dimensionales convenientes. Sin embargo, al insertar uno siempre se debe verificar si el primer índice ya existe en el hash. Por ejemplo:

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

Sería preferible hacer lo siguiente donde el nuevo Hash se crea automáticamente:

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

Del mismo modo, al buscar un valor donde el primer índice no existe, sería preferible si se devuelve nil en lugar de recibir un método indefinido para el error ''[]''.

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

Uno podría crear una clase contenedora Hash que tenga este comportamiento, pero ¿existe un modismo Ruby existente para llevar a cabo esta tarea?


Puede pasar la función Hash.new un bloque que se ejecuta para generar un valor predeterminado en caso de que el valor consultado aún no exista:

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

Por supuesto, esto se puede hacer recursivamente.

/ EDITAR: Wow, hay un artículo que responde esta misma pregunta.

En aras de la exhaustividad, esta es la solución del artículo para hashes de profundidad arbitrarios:

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

Los créditos van a Kent desde Data Noise .