测试数组

正确的方法是什么:

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


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

或者获取其中的条目数?

265290 次浏览

你可能想要使用kind_of()

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

试一试:

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

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

你确定需要是一个数组吗?你可以使用respond_to?(method),这样你的代码就可以用于类似的东西,不一定是数组(可能是其他一些可枚举的东西)。如果你确实需要一个array方法,那么描述Array#kind\_of?方法的帖子是最好的。

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

听起来你想要的东西有一些项目的概念。因此,我建议查看它是否为Enumerable。这也保证了#count的存在。

例如,

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

注意,虽然sizelengthcount都适用于数组,但这里的正确含义是count(例如,'abc'.length'abc'.size都适用,但'abc'.count不适用)。

注意:字符串is_a?可枚举的,所以也许这不是你想要的…这取决于你对数组的概念,比如object。

而不是测试Array,,只需将你得到的任何东西转换为一级Array,,这样你的代码只需要处理一种情况。

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

Ruby有各种方法来协调API,这些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]"

或者,你可以在参数声明中使用长条木板,然后使用.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]"

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

[1,2,3].is_a? Array的值为true。

也可以考虑使用Array()。从Ruby社区风格指南:

处理时使用Array()而不是显式的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) }