oaklodge
oaklodge

Reputation: 748

Ruby array contains types?

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

Answers (4)

Jörg W Mittag
Jörg W Mittag

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

SRack
SRack

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

Ahmed Magdy
Ahmed Magdy

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

Oleksandr Holubenko
Oleksandr Holubenko

Reputation: 4440

You can try #any?

For example:

[1,"a",[],:asdf].any? { |el| el.is_a? Array }
#=> true

Upvotes: 4

Related Questions