Какой правильный способ:
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
kind_of?()
поверх других решений? Некоторое объяснение преимуществ вашего ответа перед другими будет полезно для будущих читателей.
Вы уверены, что это должен быть массив? Вы можете использовать его respond_to?(method)
так, чтобы ваш код работал для похожих вещей, которые не обязательно являются массивами (возможно, для некоторых других перечисляемых вещей). Если вам на самом деле нужен array
, то Array#kind\_of?
лучше всего пост, описывающий метод.
['hello'].respond_to?('each')
respond_to?(:to_ary)
.
Вместо того, чтобы тестировать Array,
просто преобразовать все, что вы получаете в одноуровневый, Array,
ваш код должен обрабатывать только один случай.
t = [*something] # or...
t = Array(something) # or...
def f *x
...
end
Рубин имеет различные пути согласования в API , который может принимать объект или массив объектов, поэтому, принимая догадываться , почему вы хотите знать , если что - то есть массив, у меня есть предложение.
Оператор 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]"
Или вы можете использовать знак восклицательного знака в объявлении параметра, а затем .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
ему не нужно создавать новый объект.
[*nil] => []
. Таким образом, вы можете получить пустой массив.
Array(foo)
гораздо эффективнее, чем[*foo]
[1,2,3].is_a? Array
оценивает как истинное.
is_a?
на всю цепочку. Ближайшим является [1,2,3].is_a? Enumerable
. Я все еще думаю, что стоит получить этот ответ.
Похоже, вы ищете что-то, что имеет некоторое представление о предметах. Поэтому я бы порекомендовал посмотреть, если это так Enumerable
. Это также гарантирует существование #count
.
Например,
[1,2,3].is_a? Enumerable
[1,2,3].count
отметить , что, в то время как size
, length
и count
все работы для массивов, count
это правильный смысл здесь - (к примеру, 'abc'.length
и 'abc'.size
оба работают, но 'abc'.count
не работает , как это).
Осторожно: строка is_a? Enumerable, так что, возможно, это не то, что вам нужно ... зависит от вашей концепции массива, подобного объекту.
Пытаться:
def is_array(a)
a.class == Array
end
РЕДАКТИРОВАТЬ : другой ответ гораздо лучше, чем мой.
Также подумайте об использовании Array()
. Из Руководства по стилю сообщества Ruby :
Используйте Array () вместо явной проверки Array или [* var], когда имеете дело с переменной, которую вы хотите рассматривать как Array, но не уверены, что это массив.
# 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) }
to_a
вызывается для каждого аргумента, добавленного в новый массив, поэтому Array({id: 100})
возвращается[[:id, 100]]