Ruby中用什么优雅的方法来判断变量是哈希还是数组?

问题描述 投票:128回答:9

要检查@some_var是什么,我正在做一个

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

我确信有一种更优雅的方法来检查@some_varHash还是Array

ruby arrays hash
9个回答
247
投票

您可以做:

@some_var.class == Hash

或也类似:

@some_var.is_a?(Hash)

值得注意的是,“ is_a?”如果该类在对象祖先树中的任何位置,则方法为true。例如:

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

如果@some_var是源自Object的哈希或其他类的实例,则为true。因此,如果要对类类型进行严格匹配,请使用==或instance_of?方法可能是您要寻找的。


37
投票

首先,对于字面问题的最佳答案是

Hash === @some_var

但是这个问题确实应该通过在此处显示如何进行鸭式打字来回答。这取决于您需要哪种鸭子。

@some_var.respond_to?(:each_pair)

@some_var.respond_to?(:has_key?)

甚至

@some_var.respond_to?(:to_hash)

可能取决于应用程序。


25
投票

通常在红宝石中,当您寻找“类型”时,您实际上想要的是“鸭子类型”或“像鸭子一样嘎嘎吗?”。您将看到它是否响应某种方法:

@some_var.respond_to?(:each)

您可以遍历@some_var,因为它会响应:each

如果您真的想知道类型,并且它是哈希或数组,则可以:

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

12
投票
Hash === @some_var #=> return Boolean

也可以与case语句一起使用

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

4
投票

我使用这个:

@var.respond_to?(:keys)

它适用于Hash和ActiveSupport :: HashWithIndifferentAccess。


4
投票

实际上,您经常希望根据变量是数组还是哈希而不是仅仅告诉变量来采取不同的行动。在这种情况下,elegant习惯用法如下:

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

请注意,您不会在.class上调用item方法。


2
投票

您可以使用instance_of?

例如

@some_var.instance_of?(Hash)

0
投票

如果要测试对象是否严格或扩展了Hash,请使用:

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

但是要让Ruby的鸭子打字更有价值,您可以做类似的事情:

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

仅在您只想使用value[:key]语法访问某些值时很有用。

请注意,Array.new["key"]将引发TypeError


-1
投票
irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array
© www.soinside.com 2019 - 2024. All rights reserved.