Class: Range

Inherits:
Object show all
Defined in:
lib/epitools/core_ext/range.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.optimize(ranges) ⇒ Object

Takes an array of ranges, and returns a new array where all overlapping ranges are combined into a single range



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/epitools/core_ext/range.rb', line 70

def self.optimize(ranges)
  ranges = ranges.sort_by(&:first)

  result = [ranges.first]

  ranges[1..-1].each do |elem|
    if result[-1].overlaps?(elem)
      result[-1] = (result[-1] | elem)
    else
      result << elem
    end
  end

  result
end

Instance Method Details

#&(other) ⇒ Object

Return a new range which is the intersection of the two ranges



28
29
30
31
32
# File 'lib/epitools/core_ext/range.rb', line 28

def &(other)
  mins, maxes = minmax.zip(other.minmax)

  (mins.max..maxes.min)
end

#actual_lastObject

The actual last value in the range (eg: ‘(1…10).actual_last == 9`)



6
7
8
# File 'lib/epitools/core_ext/range.rb', line 6

def actual_last
  exclude_end? ? last - 1 : last
end

#merge(other) ⇒ Object

Merge this range with another (if the two ranges overlap, then it returns an array containing a single merged range; if the two ranges are disjoint, an array with the two ranges is returned)



51
52
53
54
55
56
57
# File 'lib/epitools/core_ext/range.rb', line 51

def merge(other)
  if self.overlaps?(other)
    [self | other]
  else
    [self, other]
  end
end

#midObject Also known as: middle

The number in the middle of this range.



20
21
22
# File 'lib/epitools/core_ext/range.rb', line 20

def mid
  (min + max) / 2
end

#overlaps?(other) ⇒ Boolean

Test if this range overlaps the other

Returns:

  • (Boolean)


62
63
64
65
# File 'lib/epitools/core_ext/range.rb', line 62

def overlaps?(other)
  # overlap == start < finish' AND start' < finish
  self.first <= other.actual_last and other.first <= self.actual_last
end

#randObject

Pick a random number from the range.



13
14
15
# File 'lib/epitools/core_ext/range.rb', line 13

def rand
  Kernel.rand(self)
end

#|(other) ⇒ Object

Return a new range which is the union of the two ranges (even if the two ranges don’t overlap)



37
38
39
40
41
42
43
44
45
46
# File 'lib/epitools/core_ext/range.rb', line 37

def |(other)
  vals = [
    first,
    other.first,
    actual_last,
    other.actual_last
  ].sort

  (vals.first..vals.last)
end