it-swarm.com.de

Was ist eine einfache/elegante Methode in Ruby, um herauszufinden, ob eine bestimmte Variable ein Hash oder ein Array ist?

Um zu überprüfen, was @some_var ist, mache ich ein

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

Ich bin sicher, es gibt eine elegantere Methode, um zu überprüfen, ob @some_var eine Hash oder eine Array ist.

117
drhyde

Sie können einfach tun:

@some_var.class == Hash

oder auch so etwas:

@some_var.is_a?(Hash)

Es ist erwähnenswert, dass das "is_a?" Die Methode ist true, wenn sich die Klasse irgendwo im Objektvorfahrenbaum befindet. zum Beispiel:

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

das obige ist wahr, wenn @some_var eine Instanz eines Hash oder einer anderen Klasse ist, die von Object stammt. Wenn Sie also eine strikte Übereinstimmung des Klassentyps wünschen, verwenden Sie == oder instance_of? Methode ist wahrscheinlich das, wonach Sie suchen. 

225
Pete

Zuallererst ist die beste Antwort auf die wörtliche Frage

Hash === @some_var

Aber die Frage hätte eigentlich beantwortet werden müssen, indem gezeigt wurde, wie man hier Ente schreibt. Das hängt davon ab, welche Art Ente man braucht.

@some_var.respond_to?(:each_pair)

oder

@some_var.respond_to?(:has_key?)

oder auch

@some_var.respond_to?(:to_hash)

kann je nach Anwendung richtig sein.

33
cabo

Normalerweise in Ruby, wenn Sie nach "type" suchen, möchten Sie eigentlich den "duck-type" oder "quake wie eine Ente?". Sie würden sehen, wenn es auf eine bestimmte Methode reagiert: 

@some_var.respond_to?(:each)

Sie können über @some_var iterieren, da jeweils auf Folgendes reagiert wird

Wenn Sie wirklich wissen wollen, um welchen Typ es sich handelt, und ob es sich um Hash oder Array handelt, können Sie Folgendes tun:

["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

dies kann auch mit der Case-Anweisung verwendet werden

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

Ich benutze das:

@var.respond_to?(:keys)

Es funktioniert für Hash und ActiveSupport :: HashWithIndifferentAccess.

4
drinor

In der Praxis werden Sie häufig unterschiedlich handeln, je nachdem, ob eine Variable ein Array oder ein Hash ist, und nicht nur ein Tell. In dieser Situation lautet ein elegantes Idiom:

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

Beachten Sie, dass Sie die .class-Methode nicht für item aufrufen. 

3

Sie können instance_of? verwenden

z.B

@some_var.instance_of?(Hash)
2
Shiv

Wenn Sie testen möchten, ob ein Objekt eine Hash streng ist oder erweitert, verwenden Sie:

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

Aber um den Wert von Rubys Entenschreibung zu verbessern, können Sie Folgendes tun:

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

Dies ist nützlich, wenn Sie nur mit der value[:key]-Syntax auf einen Wert zugreifen möchten.

Bitte beachten Sie, dass Array.new["key"] eine TypeError erhöht.

0
vnbrs