Question

La création de hachages de hachages en Ruby permet d'effectuer des recherches bidimensionnelles (ou plus). Cependant, lors de l'insertion, il faut toujours vérifier si le premier index existe déjà dans le hachage. Par exemple:

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

Il serait préférable de procéder comme suit lorsque le nouveau hachage est créé automatiquement:

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

De même, lors de la recherche d'une valeur où le premier index n'existe pas déjà, il serait préférable de renvoyer la valeur nil plutôt que de recevoir une méthode non définie pour l'erreur '[]'.

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

On pourrait créer une classe wrapper de hachage présentant ce comportement, mais existe-t-il un idiotisme Ruby pour accomplir cette tâche?

Était-ce utile?

La solution

Vous pouvez transmettre le Hash.new fonctionne un bloc qui est exécuté pour donner une valeur par défaut au cas où la valeur demandée n'existe pas encore:

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

Bien sûr, cela peut être fait de manière récursive.

/ EDIT: Wow, il y a un article répondant à cette question même.

Par souci d'exhaustivité, voici la solution de l'article pour les hachages de profondeur arbitraires:

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

Les crédits vont à Kent à partir de bruit des données .

Autres conseils

L'autovivification, comme on l'appelle, est à la fois une bénédiction et une malédiction. Le problème peut être que si vous regardez " à une valeur avant sa définition, vous êtes coincé avec ce hachage vide dans la fente et vous devrez le supprimer plus tard.

Si l'anarchie ne vous dérange pas, vous pouvez toujours insérer des déclarations de style ou égales qui vous permettront de construire la structure attendue lorsque vous l'interrogerez:

((h ||= { })['w'] ||= { })['z']
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top