Ruby - 测试数组

Bud*_*Joe 259 ruby syntax

什么是正确的方法:

is_array("something") # => false         (or 1)

is_array(["something", "else"]) # => true  (or > 1)
Run Code Online (Sandbox Code Playgroud)

或者计算其中的物品数量?

ry.*_*ry. 504

你可能想用kind_of?().

>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
Run Code Online (Sandbox Code Playgroud)

  • 还有`is_a?`和`instance_of?`.请参阅http://stackoverflow.com/questions/3893278/ruby-kind-of-vs-instance-of-vs-is-a (30认同)
  • @ user132447实际上java是类型安全的,所以你不必担心检查任何类型 (14认同)
  • 我现在对此表示赞同,因为我不认为这是一种像Ruby这样的语言的好习惯.@zgchurch的答案显然是一个更惯用的问题方法.在这种情况下,我认为尝试找出OP意味着什么更有意义,而不是盲目地给他一把霰弹枪...... (8认同)
  • 类型检查适用于Java.继续,只需对变量进行调用计数.编写单元测试以确保方法按预期工作. (2认同)

zgc*_*rch 146

你确定它需要是一个阵列吗?您可以使用,respond_to?(method)因此您的代码可以用于类似的事情,这些事情不一定是数组(也许是其他一些令人难以理解的事情).如果你确实需要一个array,那么描述该Array#kind\_of?方法的帖子是最好的.

['hello'].respond_to?('each')
Run Code Online (Sandbox Code Playgroud)

  • 一般来说,这是面向对象开发的一个好习惯.我读到有人基本上说过的地方:不要以为你在对象上调用方法.你正在给他们发消息.如果一个对象知道如何响应你的消息,你不关心它是什么类,或者它是否有一个名为它的方法,或者它是否通过method_missing动态创建一个响应.重要的是,它能回应你的信息吗?这样可以更好地抽象功能和实现.您可以更改以后使用的对象,只要它仍然可以正确响应. (20认同)
  • 鸭子为胜利打字!希望我能两次投票. (4认同)
  • 如果你想要更像数组的东西,你可能需要`respond_to?(:to_ary)`. (3认同)
  • 唯一的问题是我想检查某些东西是否是索引的可迭代的,所以数组,链表等会很酷,但我不想像哈希这样的键值存储? (2认同)

Dig*_*oss 57

而不是测试Array,只是转换为一个级别的任何东西,Array,所以你的代码只需要处理一个案例.

t = [*something]     # or...
t = Array(something) # or...
def f *x
    ...
end
Run Code Online (Sandbox Code Playgroud)

Ruby有各种方法可以协调一个API,它可以接受一个对象或一个对象数组,所以,猜测你想知道某些东西是否是一个数组的原因,我有一个建议.

图示操作含有大量的魔法你可以看一下,或者你可以拨打Array(something)如果需要的话,这将增加一个阵列封装.它与[*something]这一例类似.

def f x
  p Array(x).inspect
  p [*x].inspect
end
f 1         # => "[1]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"
Run Code Online (Sandbox Code Playgroud)

或者,您可以在参数声明中使用splat,然后.flatten为您提供不同类型的收集器.(就此而言,你也可以.flatten在上面打电话.)

def f *x
  p x.flatten.inspect
end         # => nil
f 1         # => "[1]"
f 1,2       # => "[1, 2]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"
f [1,2],3,4 # => "[1, 2, 3, 4]"
Run Code Online (Sandbox Code Playgroud)

并且,感谢gregschlom,它有时更快才被使用,Array(x)因为当它已经是一个Array它不需要创建一个新对象.

  • 使用`Array(foo)`比`[*foo]`更有效 (3认同)
  • 别忘了:`[*nil] => []`.所以你最终可能得到一个空数组. (2认同)

dip*_*ent 20

[1,2,3].is_a? Array 评估为真.

  • @Carpetsmoker没有一个简洁的答案,在整个帖子中引用了``is_a?``.最接近的是``[1,2,3] .is_a?Enumerable``.我仍然认为有这个答案是值得的. (5认同)
  • 你知道......你真的是对的...我可以发誓我早先看到那里: - /有一个upvote! (4认同)

Pet*_*ter 15

这听起来像是在追求具有某些物品概念的东西.我因此建议看看它是不是Enumerable.这也保证了存在#count.

例如,

[1,2,3].is_a? Enumerable
[1,2,3].count
Run Code Online (Sandbox Code Playgroud)

值得注意的是,虽然size,lengthcount数组的所有工作,count是在这里的意思- (例如,'abc'.length'abc'.size两个工作,但'abc'.count好像不工作).

警告:字符串is_a?可枚举,所以也许这不是你想要的......取决于你的对象数组的概念.


Luc*_*nes 10

尝试:

def is_array(a)
    a.class == Array
end
Run Code Online (Sandbox Code Playgroud)

编辑:另一个答案比我的好得多.


Guy*_*ock 6

还考虑使用Array().来自Ruby社区风格指南:

在处理要作为数组处理的变量时,使用Array()而不是显式数组检查或[*var],但您不确定它是否为数组.

# bad
paths = [paths] unless paths.is_a? Array
paths.each { |path| do_something(path) }

# bad (always creates a new Array instance)
[*paths].each { |path| do_something(path) }

# good (and a bit more readable)
Array(paths).each { |path| do_something(path) }
Run Code Online (Sandbox Code Playgroud)