Ruby中用什么简单/优雅的方式判断特定变量是Hash还是数组?

时间:2011-03-20 06:28:23

标签: ruby arrays hash

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

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

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

9 个答案:

答案 0 :(得分:230)

你可以这样做:

@some_var.class == Hash

或类似的东西:

@some_var.is_a?(Hash)

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

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

如果@some_var是源自Object的散列或其他类的实例,则上述情况属实。那么,如果你想要类类型的严格匹配,使用==或instance_of?方法可能就是你要找的东西。

答案 1 :(得分:35)

首先,文字问题的最佳答案是

Hash === @some_var

但问题确实应该通过展示如何在这里进行鸭子打字来回答。 这取决于你需要什么样的鸭子。

@some_var.respond_to?(:each_pair)

@some_var.respond_to?(:has_key?)

甚至

@some_var.respond_to?(:to_hash)

可能是正确的,具体取决于申请。

答案 2 :(得分:25)

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

@some_var.respond_to?(:each)

你可以迭代@some_var,因为它响应:每个

如果您真的想知道类型,如果它是Hash或Array,那么您可以这样做:

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

答案 3 :(得分:11)

Hash === @some_var #=> return Boolean

这也可以与案例陈述

一起使用
case @some_var
when Hash
   ...
when Array
   ...
end

答案 4 :(得分:4)

我用这个:

@var.respond_to?(:keys)

适用于Hash和ActiveSupport :: HashWithIndifferentAccess。

答案 5 :(得分:4)

在实践中,您通常希望采取不同的行动,具体取决于变量是数组还是哈希,而不仅仅是告诉。在这种情况下,优雅的成语如下:

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

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

答案 6 :(得分:2)

您可以使用instance_of?

e.g

@some_var.instance_of?(Hash)

答案 7 :(得分:0)

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

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

但是要使Ruby的鸭子打字更有价值,您可以执行以下操作:

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

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

  

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

答案 8 :(得分:-1)

irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array