Ruby – testing数组

什么是正确的方法来:

is_array("something") # => false (or 1) is_array(["something", "else"]) # => true (or > 1) 

或得到它的项目数?

你可能想使用kind_of?()

 >> s = "something" => "something" >> s.kind_of?(Array) => false >> s = ["something", "else"] => ["something", "else"] >> s.kind_of?(Array) => true 

你确定它需要是一个数组? 你可能能够使用respond_to?(method)所以你的代码将适用于类似的东西,不一定是数组(可能是一些其他的可执行的东西)。 如果你确实需要一个array ,那么描述Array#kind\_of? 方法是最好的。

 ['hello'].respond_to?('each') 

而不是testing一个Array,只需要将你得到的数据转换成一个一级Array,所以你的代码只需要处理一个情况。

 t = [*something] # or... t = Array(something) # or... def f *x ... end 

Ruby有多种方法可以协调一个可以接受一个对象或一个数组对象的API,因此,为了猜测为什么要知道某个数组什么,我有一个build议。

splat运算符包含了许多可以查找的魔法,或者您可以调用Array(something) ,如果需要,它将添加一个Array包装器。 在这种情况下,它类似于[*something]

 def fx p Array(x).inspect p [*x].inspect end f 1 # => "[1]" f [1] # => "[1]" f [1,2] # => "[1, 2]" 

或者,你可以在参数声明中使用splat ,然后使用.flatten ,给你一个不同types的收集器。 (对于这个问题,你也可以打上面的。)

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

而且,感谢gregschlom ,使用Array(x)有时会更快,因为当它已经是一个Array它不需要创build一个新的对象。

这听起来像是你在追求一些有一些项目概念的东西。 因此,我build议看看它是否Enumerable 。 这也保证了#count的存在。

例如,

 [1,2,3].is_a? Enumerable [1,2,3].count 

请注意,虽然sizelengthcount都适用于数组,但count在这里是正确的含义 – (例如, 'abc'.length 'abc'.size'abc'.size都可以工作,但是'abc'.count不起作用那)。

警告:一个stringis_a? 可枚举的,所以也许这不是你想要的…取决于你的对象的数组的概念。

[1,2,3].is_a? Array [1,2,3].is_a? Array计算结果为true。

尝试:

 def is_array(a) a.class == Array end 

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

另外考虑使用Array() 。 从Ruby社区风格指南 :

使用Array()而不是显式数组检查或[* var],当处理一个你想作为一个数组对待的variables,但你不能确定它是一个数组。

 # 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) }