Reputation: 45
Is there a simple way of mapping a range to another kind of range in ruby without iterating over the whole range? Basically what I'm trying to achieve is this
## mapping this
range = 1..5
## into this
date_range = (1.year.ago)..(5.years.ago)
The best I came up with was this:
(range.begin.years.ago)..(range.end.years.ago)
Is there a method that would let me do something like:
range.map {|e| e.years.ago}
Upvotes: 3
Views: 1238
Reputation: 15954
There is currently (Ruby 2.2.2) no better way than just
(range.begin.years.ago)..(range.end.years.ago)
If you look into the documentation of Range, you see that none of the methods directly implement something like that.
Then, there is the included module Enumerable
which already looses the range semantics (being defined by first and last element).
You could monkey-patch it yourself like:
class Range
def rmap(&b)
Range.new(yield(self.begin), yield(self.end), exclude_end?)
end
end
and then do (years.ago
requires ActiveSupport/Rails):
(1..5).rmap { | a | a.years.ago }
Obviously, the block has to yield values suitable for creating a range.
Upvotes: 4