48 votes

Accéder aux éléments de hachages imbriqués dans ruby

Je travaille sur un petit utilitaire écrit en ruby qui utilise largement les hachages imbriqués. Actuellement, je vérifie l'accès aux éléments de hachage imbriqués comme suit :

 structure = { :a => { :b => 'foo' }}

# I want structure[:a][:b]

value = nil

if structure.has_key?(:a) && structure[:a].has_key?(:b) then
  value = structure[:a][:b]
end

Y a-t-il une meilleure manière de faire cela? J'aimerais pouvoir dire :

 value = structure[:a][:b]

Et obtenez nil si :a n'est pas une clé dans structure , etc.

68voto

DigitalRoss Points 80400

Traditionnellement, il fallait vraiment faire quelque chose comme ça :

 structure[:a] && structure[:a][:b]

Cependant, Ruby 2.3 a ajouté une méthode Hash#dig qui rend cette façon plus gracieuse :

 structure.dig :a, :b # nil if it misses anywhere along the way

Il y a un joyau appelé ruby_dig qui le corrigera pour vous.

48voto

Jesse Sielaff Points 1443

Ruby 2.3.0 a introduit une nouvelle méthode appelée dig à la fois sur Hash et Array qui résout entièrement ce problème.

 value = structure.dig(:a, :b)

Il renvoie nil si la clé est manquante à n'importe quel niveau.

Si vous utilisez une version de Ruby antérieure à 2.3, vous pouvez utiliser le gem ruby_dig

14voto

Cheng Points 1320

J'ai fait rubygem pour ça. Essayez la vigne .

Installer:

 gem install vine

Usage:

 hash.access("a.b.c")

7voto

Javid Jamae Points 2971

Je pense que l'une des solutions les plus lisibles est d'utiliser Hashie :

 require 'hashie'
myhash = Hashie::Mash.new({foo: {bar: "blah" }})

myhash.foo.bar
=> "blah"    

myhash.foo?
=> true

# use "underscore dot" for multi-level testing
myhash.foo_.bar?
=> true
myhash.foo_.huh_.what?
=> false

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X