Reputation: 748
I need a function to check if an array contains other arrays, or more generally if an array contains a certain class. My naive first approach is:
found=false
[1,"a",[],:asdf].each { |x| found=(x.is_a? Array) ? true : found }
puts found
Any way to optimize this?
Upvotes: 3
Views: 1228
Reputation: 369526
Almost always when you find yourself using each
, you are missing some higher-level abstraction.
In this case, that abstraction is the method Array#any?
, which will return true
if any element of the array satisfies the predicate:
[1, "a", [], :asdf].any?(Array)
Upvotes: 2
Reputation: 12203
In newer Rubies (2.5+
) you don't need to pass a block to any?
. That links goes to the latest docs, which has a similar example checking for integers.
Therefore, you can simply use:
[1, "a", [], :asdf].any?(Array)
# => true
[1, "a", :asdf].any?(Array)
# => false
That seems the simplest syntax and most sensible approach here if your Ruby version allows it :)
Upvotes: 6
Reputation: 92
this approach iterate over all elements even if you found an array. in your test case it will iterate over :asdf, and you don't have to check this.
I think you need to break from loop if you found the certain type(Array in our Example).
found = false
[1,"a",[],:asdf].each do |x|
if x.is_a? Array
found = true
break
end
end
puts found
Also you can use any instead of each
found = [1,"a",[],:asdf].any? { |x| x.is_a? Array }
puts found # true
Upvotes: 1
Reputation: 4440
You can try #any?
For example:
[1,"a",[],:asdf].any? { |el| el.is_a? Array }
#=> true
Upvotes: 4