Class: RangeSet
- Inherits:
- 
      Object
      
        - Object
- RangeSet
 
- Includes:
- Enumerable
- Defined in:
- lib/rangeset.rb,
 lib/rangeset/version.rb
Constant Summary collapse
- VERSION =
- "0.1.3"
Instance Attribute Summary collapse
- 
  
    
      #ranges  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute ranges. 
Class Method Summary collapse
- .[](*ranges) ⇒ Object
- .build(ranges) ⇒ Object
- .diff(left, right, intersect_only = false) ⇒ Object
- .difference(left, right) ⇒ Object
- .intersection(left, right) ⇒ Object
- .union(left, right) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #combine(ranges) ⇒ Object
- #diff(other) ⇒ Object
- #difference(other) ⇒ Object
- #each(&block) ⇒ Object
- #first ⇒ Object
- #gaps ⇒ Object
- #include?(n) ⇒ Boolean
- 
  
    
      #initialize(*ranges)  ⇒ RangeSet 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    A new instance of RangeSet. 
- #inspect ⇒ Object
- #intersection(other) ⇒ Object
- #last ⇒ Object
- #union(other) ⇒ Object
Constructor Details
#initialize(*ranges) ⇒ RangeSet
Returns a new instance of RangeSet.
| 89 90 91 92 93 94 95 96 97 98 99 | # File 'lib/rangeset.rb', line 89 def initialize(*ranges) if ranges.length > 1 @ranges = combine ranges else if ranges.first.is_a? RangeSet @ranges = ranges.first.ranges else @ranges = ranges end end end | 
Instance Attribute Details
#ranges ⇒ Object (readonly)
Returns the value of attribute ranges.
| 87 88 89 | # File 'lib/rangeset.rb', line 87 def ranges @ranges end | 
Class Method Details
.[](*ranges) ⇒ Object
| 9 10 11 | # File 'lib/rangeset.rb', line 9 def [](*ranges) build ranges end | 
.build(ranges) ⇒ Object
| 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # File 'lib/rangeset.rb', line 13 def build(ranges) if ranges if ranges.is_a? Array ranges = ranges.compact if ranges.length == 1 and ranges.first.is_a? Range ranges.first elsif ranges.count == 0 nil else RangeSet.new *ranges end elsif ranges.is_a? Range or ranges.is_a? RangeSet ranges elsif ranges.is_a? Fixnum ranges..ranges end end end | 
.diff(left, right, intersect_only = false) ⇒ Object
| 75 76 77 78 79 80 81 82 | # File 'lib/rangeset.rb', line 75 def diff(left, right, intersect_only = false) return [left, nil, nil] unless right return [nil, nil, right] unless left int = intersection(left, right) in_left = difference left, int in_right = difference right, int [in_left, int, in_right] end | 
.difference(left, right) ⇒ Object
| 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | # File 'lib/rangeset.rb', line 59 def difference(left, right) if not right left elsif left left.ranges.reduce(nil) do |result, l| in_left = right.ranges.map do |r| l.difference(r) end in_left = in_left.reduce { |int, il| intersection int, il } union result, in_left end end end | 
.intersection(left, right) ⇒ Object
| 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | # File 'lib/rangeset.rb', line 44 def intersection(left, right) if not left or not right nil elsif left.is_a? Range and right.is_a? Range left.intersection right else left.ranges.reduce(nil) do |result, left| intersections = right.ranges.map do |right| left.intersection right end union(result, RangeSet.build(intersections)) end end end | 
Instance Method Details
#==(other) ⇒ Object
| 175 176 177 178 179 180 181 182 | # File 'lib/rangeset.rb', line 175 def ==(other) !!( if other.is_a? RangeSet ranges == other.ranges elsif other.is_a? Range and ranges.count == 1 ranges == [other] end) end | 
#combine(ranges) ⇒ Object
| 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # File 'lib/rangeset.rb', line 101 def combine(ranges) ranges = ranges.compact.flat_map do |r| if r.is_a? RangeSet r.ranges elsif r.is_a? Range [r] elsif r.is_a? Fixnum [r..r] else [] end end ranges = ranges.compact.sort_by(&:first) result = [ranges.first] ranges[1..-1].each do |r| l = result.last if l.last >= r.first if l.last >= r.last next else result.pop r = l.first..r.last end elsif l.last + 1 == r.first result.pop r = l.first..r.last end result.push r end result end | 
#diff(other) ⇒ Object
| 159 160 161 | # File 'lib/rangeset.rb', line 159 def diff(other) RangeSet.diff self, other end | 
#difference(other) ⇒ Object
| 171 172 173 | # File 'lib/rangeset.rb', line 171 def difference(other) RangeSet.difference self, other end | 
#each(&block) ⇒ Object
| 137 138 139 140 141 142 143 144 145 | # File 'lib/rangeset.rb', line 137 def each(&block) if block ranges.each do |range| range.each &block end else to_enum :each end end | 
#first ⇒ Object
| 147 148 149 | # File 'lib/rangeset.rb', line 147 def first ranges.first.first end | 
#gaps ⇒ Object
| 133 134 135 | # File 'lib/rangeset.rb', line 133 def gaps RangeSet.build ranges.each_cons(2).map { |a, b| (a.last + 1)..(b.first - 1) } end | 
#include?(n) ⇒ Boolean
| 155 156 157 | # File 'lib/rangeset.rb', line 155 def include?(n) ranges.any? { |r| r.include? n } end | 
#inspect ⇒ Object
| 184 185 186 | # File 'lib/rangeset.rb', line 184 def inspect "RangeSet#{ ranges.inspect }" end | 
#intersection(other) ⇒ Object
| 167 168 169 | # File 'lib/rangeset.rb', line 167 def intersection(other) RangeSet.intersection self, other end | 
#last ⇒ Object
| 151 152 153 | # File 'lib/rangeset.rb', line 151 def last ranges.last.last end |