Каков правильный способ:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
или получить количество элементов в нем?
Каков правильный способ:
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')
Вместо тестирования для Array,
просто преобразуйте все, что вы получаете, в одноуровневое Array,
, поэтому ваш код должен обрабатывать только один случай.
t = [*something] # or...
t = Array(something) # or...
def f *x
...
end
Ruby имеет различные способы согласования API, который может принимать объект или массив объектов, поэтому, угадывая, почему вы хотите узнать, является ли что-то Array, у меня есть предложение.
Оператор splat содержит много волшебства вы можете искать, или вы можете просто вызвать Array(something)
, который добавит оболочку Array, если необходимо. Это похоже на [*something]
в этом случае.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1 # => "[1]"
f [1] # => "[1]"
f [1,2] # => "[1, 2]"
Или вы можете использовать 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]"
И, спасибо gregschlom, иногда быстрее использовать Array(x)
, потому что, когда он уже есть Array
, ему не нужно создавать новую объект.
Похоже, вы за чем-то, у которого есть понятие об элементах. Поэтому я рекомендую посмотреть, есть ли Enumerable
. Это также гарантирует существование #count
.
Например,
[1,2,3].is_a? Enumerable
[1,2,3].count
обратите внимание, что, хотя size
, length
и count
все работают для массивов, count
здесь является правильным значением (например, 'abc'.length
и 'abc'.size
работают, но 'abc'.count
не работает).
Внимание: строка is_a? Перечислим, так что, возможно, это не то, что вы хотите... зависит от вашей концепции массива как объекта.
[1,2,3].is_a? Array
имеет значение true.
Try:
def is_array(a)
a.class == Array
end
EDIT: другой ответ намного лучше, чем мой.
Также рассмотрите возможность использования 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) }