Вы хотите фактический массив, или просто что-то вроде массива?
Кэти Ван Стоун
1
В Ruby нет безопасности типов. Не беспокойтесь о том, что ваша переменная является массивом или нет. Метод должен предполагать, что это так, и идти вперед и подсчитывать количество вызовов: my_array.count
user132447
Пожалуйста, прочитайте ответы zgchurch и DigitalRoss для более идиоматического Ruby.
Проверка типов для Java. Продолжайте и просто посчитайте на переменную. Напишите модульные тесты, чтобы убедиться, что метод работает должным образом.
user132447
14
@ user132447 на самом деле java является безопасным типом, поэтому вам не нужно беспокоиться о проверке любых типов
grinch
8
Я понизил это сейчас, так как не думаю, что это хорошая практика для такого языка, как Ruby. Ответ @zgchurch - явно более идиоматический подход к вопросу. В таких случаях, мне кажется, гораздо разумнее попытаться выяснить, что означает ОП, чем слепо давать ему дробовик ...
Пер Лундберг,
1
Почему вы хотите использовать kind_of?()поверх других решений? Некоторое объяснение преимуществ вашего ответа перед другими будет полезно для будущих читателей.
AlbertEngelB
148
Вы уверены, что это должен быть массив? Вы можете использовать его respond_to?(method)так, чтобы ваш код работал для похожих вещей, которые не обязательно являются массивами (возможно, для некоторых других перечисляемых вещей). Если вам на самом деле нужен array, то Array#kind\_of?лучше всего пост, описывающий метод.
В этом случае я уверен, что это будет массив. Но приятно знать и этот метод. +1
BuddyJoe
Интересная идея, я использую push / pop для структуры данных. Будет ли что-нибудь кроме массивов отвечать на эти методы?
Дрю
3
Если вы хотите что-то более похожее на массив, вы можете захотеть respond_to?(:to_ary).
Эндрю Гримм
21
В целом, это хорошая практика для развития ОО. Я прочитал, где кто-то сказал в принципе: не думайте, что вы вызываете методы для своих объектов. Вы отправляете им сообщения. Если объект знает, как ответить на ваше сообщение, вам все равно, к какому классу он относится, имеет ли он метод с таким именем или динамически создает ответ с помощью method_missing. Важно, может ли он ответить на ваше сообщение? Это позволяет лучше абстрагировать функцию и реализацию. Вы можете изменить, какой объект вы используете позже, если он по-прежнему правильно реагирует.
Натан Лонг
2
Единственная проблема с этим, скажем, я хочу проверить, является ли что-то итерируемое индексированным, поэтому массивы, связанные списки и т. Д. Были бы классными, но я не хочу, чтобы хранилища значений ключей типа хэшей?
Colton Voege
58
Вместо того, чтобы тестировать 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ему не нужно создавать новый объект.
Что это добавляет к ответам, которые были на сайте в течение почти семи лет ..?
Мартин Турной
6
@Carpetsmoker нет краткого ответа, который ссылается is_a?на всю цепочку. Ближайшим является [1,2,3].is_a? Enumerable. Я все еще думаю, что стоит получить этот ответ.
dipole_moment
4
Вы знаете ... вы на самом деле правы ... Я мог бы поклясться, что видел это там раньше: - / Есть голос!
Мартин Турной
16
Похоже, вы ищете что-то, что имеет некоторое представление о предметах. Поэтому я бы порекомендовал посмотреть, если это так 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, так что, возможно, это не то, что вам нужно ... зависит от вашей концепции массива, подобного объекту.
Используйте 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]]
Ответы:
Вы, вероятно, хотите использовать
kind_of()
.источник
is_a?
иinstance_of?
. См. Stackoverflow.com/questions/3893278/…kind_of?()
поверх других решений? Некоторое объяснение преимуществ вашего ответа перед другими будет полезно для будущих читателей.Вы уверены, что это должен быть массив? Вы можете использовать его
respond_to?(method)
так, чтобы ваш код работал для похожих вещей, которые не обязательно являются массивами (возможно, для некоторых других перечисляемых вещей). Если вам на самом деле нуженarray
, тоArray#kind\_of?
лучше всего пост, описывающий метод.источник
respond_to?(:to_ary)
.Вместо того, чтобы тестировать
Array,
просто преобразовать все, что вы получаете в одноуровневый,Array,
ваш код должен обрабатывать только один случай.Рубин имеет различные пути согласования в API , который может принимать объект или массив объектов, поэтому, принимая догадываться , почему вы хотите знать , если что - то есть массив, у меня есть предложение.
Оператор splat содержит много волшебства, которое вы можете найти, или вы можете просто вызвать,
Array(something)
который добавит оболочку Array, если это необходимо. Это похоже на[*something]
это в одном случае.Или вы можете использовать знак восклицательного знака в объявлении параметра, а затем
.flatten
, давая вам другой тип коллектора. (В этом отношении, Вы могли бы также позвонить.flatten
выше.)И, благодаря gregschlom , иногда просто быстрее использовать,
Array(x)
потому что, когда он уже есть,Array
ему не нужно создавать новый объект.источник
[*nil] => []
. Таким образом, вы можете получить пустой массив.Array(foo)
гораздо эффективнее, чем[*foo]
[1,2,3].is_a? Array
оценивает как истинное.источник
is_a?
на всю цепочку. Ближайшим является[1,2,3].is_a? Enumerable
. Я все еще думаю, что стоит получить этот ответ.Похоже, вы ищете что-то, что имеет некоторое представление о предметах. Поэтому я бы порекомендовал посмотреть, если это так
Enumerable
. Это также гарантирует существование#count
.Например,
отметить , что, в то время как
size
,length
иcount
все работы для массивов,count
это правильный смысл здесь - (к примеру,'abc'.length
и'abc'.size
оба работают, но'abc'.count
не работает , как это).Осторожно: строка is_a? Enumerable, так что, возможно, это не то, что вам нужно ... зависит от вашей концепции массива, подобного объекту.
источник
Пытаться:
РЕДАКТИРОВАТЬ : другой ответ гораздо лучше, чем мой.
источник
Также подумайте об использовании
Array()
. Из Руководства по стилю сообщества Ruby :источник
to_a
вызывается для каждого аргумента, добавленного в новый массив, поэтомуArray({id: 100})
возвращается[[:id, 100]]