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

drh*_*yde 125 ruby arrays hash

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

if @some_var.class.to_s == 'Hash' 
Run Code Online (Sandbox Code Playgroud)

我确信有更优雅的方式来检查是否@some_var是一个Hash或一个Array.

Pet*_*ete 244

你可以这样做:

@some_var.class == Hash
Run Code Online (Sandbox Code Playgroud)

或者类似的东西:

@some_var.is_a?(Hash)
Run Code Online (Sandbox Code Playgroud)

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

@some_var.is_a?(Object)  # => true
Run Code Online (Sandbox Code Playgroud)

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

  • `is_a?`是最好的选项,因为它也为子类返回`true`. (19认同)
  • 小心,如果有人最终传递给你一个ActiveSupport :: HashWithIndifferentAccess实例,这可能会让你感到沮丧.它像哈希一样响应,但实际上并不是哈希.:( (7认同)
  • @unflores`ActiveSupport :: HashWithIndifferentAccess`继承自Hash,因此`@ some_var.is_a?(Hash)`在这种情况下也会返回true.(我刚才有同样的问题和HashWithIndifferentAccess案例并且从你的评论中有点困惑......所以我想澄清一下) (3认同)

cab*_*abo 37

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

Hash === @some_var
Run Code Online (Sandbox Code Playgroud)

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

@some_var.respond_to?(:each_pair)
Run Code Online (Sandbox Code Playgroud)

要么

@some_var.respond_to?(:has_key?)
Run Code Online (Sandbox Code Playgroud)

甚至

@some_var.respond_to?(:to_hash)
Run Code Online (Sandbox Code Playgroud)

可能是正确的,取决于应用程序.


Bra*_*don 25

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

@some_var.respond_to?(:each)
Run Code Online (Sandbox Code Playgroud)

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

如果你真的想知道类型,如果它是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
Run Code Online (Sandbox Code Playgroud)


Gut*_*nYe 11

Hash === @some_var #=> return Boolean
Run Code Online (Sandbox Code Playgroud)

这也可以与case语句一起使用

case @some_var
when Hash
   ...
when Array
   ...
end
Run Code Online (Sandbox Code Playgroud)