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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With