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
请注意,虽然size
, length
和count
都适用于数组,但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) }