web-dev-qa-db-fra.com

Quelle est une manière simple/élégante dans Ruby de dire si une variable est un hachage ou un tableau?

Pour vérifier ce que @some_var est, je fais un

if @some_var.class.to_s == 'Hash' 

Je suis sûr qu'il existe un moyen plus élégant de vérifier si @some_var est une Hash ou une Array.

117
drhyde

Vous pouvez juste faire:

@some_var.class == Hash

ou aussi quelque chose comme:

@some_var.is_a?(Hash)

Il est à noter que le "is_a?" La méthode est vraie si la classe est n'importe où dans l'arborescence d'ascendance des objets. par exemple:

@some_var.is_a?(Object)  # => true

ce qui précède est vrai si @some_var est une instance d'un hachage ou d'une autre classe issue d'Object. Donc, si vous voulez une correspondance stricte sur le type de classe, utilisez le == ou instance_of? méthode est probablement ce que vous recherchez. 

225
Pete

Tout d’abord, la meilleure réponse à la question littérale est

Hash === @some_var

Mais la question aurait vraiment dû être résolue en montrant comment faire une frappe au canard ici ..__ Cela dépend un peu du type de canard dont vous avez besoin.

@some_var.respond_to?(:each_pair)

ou

@some_var.respond_to?(:has_key?)

ou même

@some_var.respond_to?(:to_hash)

peut être juste selon l'application.

33
cabo

Habituellement, dans Ruby, lorsque vous recherchez "type", vous souhaitez en réalité le "type de canard" ou "est-ce un charlatan comme un canard?". Vous verriez si cela répond à une certaine méthode: 

@some_var.respond_to?(:each)

Vous pouvez parcourir @some_var car il répond à: each

Si vous voulez vraiment connaître le type et s'il s'agit d'un hachage ou d'un tableau, vous pouvez le faire:

["Hash", "Array"].include?(@some_var.class)  #=> check both through instance class
@some_var.kind_of?(Hash)    #=> to check each at once
@some_var.is_a?(Array)   #=> same as kind_of
25
Brandon
Hash === @some_var #=> return Boolean

cela peut également être utilisé avec l'instruction case

case @some_var
when Hash
   ...
when Array
   ...
end
11
GutenYe

J'utilise ceci:

@var.respond_to?(:keys)

Cela fonctionne pour Hash et ActiveSupport :: HashWithIndifferentAccess.

4
drinor

En pratique, vous voudrez souvent agir différemment selon que la variable est un tableau ou un hachage, et pas simplement un simple tell. Dans cette situation, un élégant idiome est le suivant:

case item
  when Array
   #do something
  when Hash
   #do something else
end

Notez que vous n'appelez pas la méthode .class sur item

3

Vous pouvez utiliser instance_of?

par exemple

@some_var.instance_of?(Hash)
2
Shiv

Si vous voulez tester si un objet est strictement ou étend une Hash, utilisez:

value = {}
value.is_a?(Hash) || value.is_a?(Array) #=> true

Mais pour valoriser la dactylographie de Ruby, vous pouvez faire quelque chose comme:

value = {}
value.respond_to?(:[]) #=> true

C'est utile lorsque vous voulez seulement accéder à une valeur en utilisant la syntaxe value[:key].

Veuillez noter que Array.new["key"] lèvera une TypeError.

0
vnbrs