class Range

Public Class Methods

combine(*intervals) click to toggle source

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

+(value) click to toggle source

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
-(value) click to toggle source

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(*intervals) click to toggle source

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(options_or_number = 1) click to toggle source

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
overlap?(other) click to toggle source

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
quantile(k, n=100) click to toggle source

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
to_range() click to toggle source

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
to_rng() click to toggle source

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
umbrella(r) click to toggle source

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
within?(rng) click to toggle source

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

minus_obj(value) click to toggle source

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