class Range
Public Class Methods
Combine intervals.
Range.combine(1..2, 2..4) #=> [1..4] Range.combine(1..2, 3..4) #=> [1..2, 3..4]
CREDIT: Trans
# File lib/core/facets/range/combine.rb, line 23 def self.combine(*intervals) intype = intervals.first.class result = [] intervals = intervals.collect do |i| [i.first, i.last] end intervals.sort.each do |(from, to)| #inject([]) do |result, if result.empty? or from > result.last[1] result << [from, to] elsif to > result.last[1] result.last[1] = to end #result end if intype <= Range result.collect{ |i| ((i.first)..(i.last)) } else result end end
Public Instance Methods
Add two ranges to create a range array.
Returns [Array]
CREDIT: monocle
# File lib/core/facets/range/op_add.rb, line 11 def +(value) [self, value].arrange end
Subtract one range from another producing a range array.
Examples
(1..10) - (4..6) => [1..3, 7..10] (1..10) - (9..12) => [1..8]
Returns [Array]
CREDIT: monocle
# File lib/core/facets/range/op_sub.rb, line 15 def -(value) if value.class == first.class minus_obj(value) else [minus_obj(value.first)[0], minus_obj(value.last)[1]].compact end end
Combine ranges.
(1..2).combine(2..4) #=> [1..4] (1..2).combine(3..4) #=> [1..2, 3..4]
TODO: Incorporate end-sentinal inclusion vs. exclusion.
CREDIT: Trans
# File lib/core/facets/range/combine.rb, line 12 def combine(*intervals) Range.combine(self, *intervals) end
Nudge range values
(1..5).nudge #=> 2..6 (1..5).nudge(2) #=> 3..7 (1..5).nudge(-2) #=> -1..3 (1..5).nudge(min: 1) #=> 2..5 (1..5).nudge(max: 1) #=> 1..6
CREDIT: Codeindulgence
# File lib/core/facets/range/nudge.rb, line 13 def nudge(options_or_number = 1) if options_or_number.instance_of? Fixnum {:min => options_or_number, :max => options_or_number} min = options_or_number max = options_or_number else min = options_or_number[:min].to_i max = options_or_number[:max].to_i end if exclude_end? (self.min + min)...((self.max + 1) + max) else (self.min + min)..(self.max + max) end end
Do two ranges overlap?
CREDIT: Daniel Schierbeck, Brandon Keepers
# File lib/core/facets/range/overlap.rb, line 7 def overlap?(other) include?(other.first) or other.include?(first) end
Calculate the kth n-tile in a range.
If n=4 the quantity is called a quartile, and if n=100 it is called a percentile.
@uncommon
require 'facets/range/quantile'
@return [Integer] the kth n-tile
# File lib/core/facets/range/quantile.rb, line 12 def quantile(k, n=100) return 1 if k < first return n if k >= last ((k - first) / ((last - first) / n.to_f)).to_i + 1 end
A thing really should know itself. This simply returns self.
Note: This does not internally effect the Ruby interpretor such that it can coerce Range-like objects into a Range
.
CREDIT: Trans
# File lib/core/facets/range/to_rng.rb, line 21 def to_range self end
A thing really should know itself. This simply returns self.
CREDIT: Trans
# File lib/core/facets/range/to_rng.rb, line 8 def to_rng self end
Returns a two element array of the relationship between two Ranges.
Diagram …
Relationship Returns self |-----------| r |-----------| [0,0] self |-----------| r |---------| [-1,-1] self |---------| r |-----------| [1,1] self |-----------| r |----------| [-1,0] self |-----------| r |-----------| [-1,1] etc.
Example:
(0..3).umbrella(1..2) #=> [-1,-1]
CREDIT: Trans, Chris Kappler
# File lib/core/facets/range/within.rb, line 49 def umbrella(r) s = first <=> r.first e = r.last <=> last if e == 0 if r.exclude_end? and exclude_end? e = r.max <=> max else e = (r.exclude_end? ? 0 : 1) <=> (exclude_end? ? 0 : 1) end end return s,e end
Uses the Range#umbrella
method to determine if another Range
is anywhere within this Range
.
(1..3).within?(0..4) #=> true
CREDIT: Trans
# File lib/core/facets/range/within.rb, line 10 def within?(rng) case rng.umbrella(self) when [0,0], [-1,0], [0,-1], [-1,-1] return true else return false end end
Private Instance Methods
TODO: Better name? Maybe make public?
# File lib/core/facets/range/op_sub.rb, line 26 def minus_obj(value) f = case value <=> first.succ when -1 then nil when 0 then first else #value < last.succ ? first...value : self value < last.succ ? first..(value.pred) : self end s = case last <=> value.succ when -1 then nil when 0 then last else value.succ > first ? (value.succ)..last : self end [f, s] end