Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the "effective" end of a Range?

Tags:

range

ruby

The .end of a Ruby range is the number used to specify the end of the range, whether or not the range is "exclusive of" the end. I don't understand the rationale for this design decision, but never the less, I was wondering what the most idiomatic mechanism is for determining the "effective end" of the range (i.e. greatest integer n such that range.include?(n) is true. The only mechanism I know of is last(1)[0], which seems pretty klunky.

like image 523
Peter Alfvin Avatar asked Mar 21 '23 12:03

Peter Alfvin


1 Answers

Use the Range#max method:

r = 1...10
r.end
# => 10
r.max
# => 9

max won't work for exclusive ranges if any of the endpoints is Float (see range_max in range.c for details):

(1.0...10.0).max
# TypeError: cannot exclude non Integer end value

(1.0..10.0).max
# => 10.0

As an exception, if begin > end, no error is raised and nil is returned:

(2.0...1.0).max
# => nil


Update: max works in costant time for any inclusive range and exclusive ranges of integers, it returns the same value as end and end-1, respectively. It is also O(1) if for the range holds that begin > end, in this case nil is returned. For exlusive ranges of non integer objects (String, Date, ...) or when a block is passed, it calls Enumerable#max so it have to travel all the elements in the range!

like image 146
13 revs Avatar answered Apr 02 '23 00:04

13 revs