1
a = [1, 2, 3..9, 10, 15, 20..43]
print a.include?(5) # Returns false

I was expecting it to return true, but 3..9 is not translated to [3,4,5,6,7,8,9].

I am missing something silly but I can't figure it out. Basically I want to initialize it with both regular fixnums and ranges.

3 Answers 3

7

You have to splat it

a = [1, 2, *3..9, 10, 15, 20..43]
a.include?(5) # => true
Sign up to request clarification or add additional context in comments.

3 Comments

Be careful splatting ranges though. It's very easy to create an array that won't fit into memory by splatting a range such as *1..1_000_000_000_000. The range is a very efficient way of expressing a big sequence, so if you're working with large ranges it'd be better to implement a smarter conditional test that knows how to compare against individual values, and for inclusion within ranges.
why not splat the second range as well? [1, 2, *3..9, 10, 15, *20..43]
@Nishu No reason. I just tried to show OP, what he missed, as he asked. If he need, he will splat it. :-)
3

If you would like a "lazier" approach that doesn't require you to convert ranges into array elements, try using the === (case equality) operator.

a = [1, 2, 3..9, 10, 15, 20..43]
a.any? { |x| x === 5 }

I recommend using this approach since it's far more efficient than splatting the range into separate elements.

Comments

1

Another solution, without splat.

a = [1, 2, 3..9, 10, 15, 20..43]

a.any? {|i| i.kind_of?(Range) ? i.include?(5) : i == 5 }
# => true 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.