What is the right way to:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
or to get the count of items in it?
What is the right way to:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
or to get the count of items in it?
You probably want to use kind_of?().
>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
Try:
def is_array(a)
a.class == Array
end
EDIT: The other answer is much better than mine.
Are you sure it needs to be an array? You may be able to use respond_to?(method) so your code would work for similar things that aren't necessarily arrays (maybe some other enumberable thing). If you do actually need an array, then the post describing the Array#kind_of? method is best.
['hello'].respond_to?('each')
It sounds like you're after something that has some concept of items. I'd thus recommend seeing if it is Enumerable
. That also guarantees the existence of #count
.
For example,
[1,2,3].is_a? Enumerable
[1,2,3].count
note that, while size
, length
and count
all work for arrays, count
is the right meaning here - (for example, 'abc'.length
and 'abc'.size
both work, but 'abc'.count
doesn't work like that).
Caution: a string is_a? Enumerable, so perhaps this isn't what you want... depends on your concept of an array like object.
t = [*thing]
You might want to use the splat operator *
. This is used to unwrap arrays, and it is particularly useful when you want to take an array or a single value and know how to write the code to handle it, which might be what you are working on.
In this case, you would add one level of array []
deliberately, but inside you would use *thing
, which will result in a single level array for either an array of any length or a single non-array object.
>> def f x
>> [*x].inspect
>> end
=> nil
>> f 1
=> "[1]"
>> f [1]
=> "[1]"
>> f [1,2]
=> "[1, 2]"
Or, you could use the splat in the parameter declaration and then .flatten
, giving you a different sort of collector. (For that matter, you could call .flatten
above, too.)
>> def f *x
>> 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]"