Class: Range
- Inherits:
-
Object
- Object
- Range
- Defined in:
- lib/fat_core/range.rb
Instance Method Summary collapse
- #contiguous?(other) ⇒ Boolean
-
#difference(other) ⇒ Object
(also: #-)
The difference method, -, removes the overlapping part of the other argument from self.
-
#gaps(ranges) ⇒ Object
If this range is not spanned by the ranges collectively, return an array of ranges representing the gaps in coverage.
-
#has_overlaps_within?(ranges) ⇒ Boolean
Return whether any of the ranges that are within self overlap one another.
- #intersection(other) ⇒ Object (also: #&)
-
#join(other) ⇒ Object
Return a range that concatenates this range with other; return nil if the ranges are not contiguous.
-
#left_contiguous?(other) ⇒ Boolean
Is self on the left of and contiguous to other?.
-
#overlaps(ranges) ⇒ Object
Similar to gaps, but within this range return the /overlaps/ among the given ranges.
- #overlaps?(other) ⇒ Boolean
- #proper_subset_of?(other) ⇒ Boolean
- #proper_superset_of?(other) ⇒ Boolean
-
#right_contiguous?(other) ⇒ Boolean
Is self on the right of and contiguous to other?.
-
#spanned_by?(ranges) ⇒ Boolean
Return true if the given ranges collectively cover this range without overlaps.
- #subset_of?(other) ⇒ Boolean
- #superset_of?(other) ⇒ Boolean
-
#tex_quote ⇒ Object
Allow erb documents can directly interpolate ranges.
- #union(other) ⇒ Object (also: #+)
Instance Method Details
#contiguous?(other) ⇒ Boolean
32 33 34 |
# File 'lib/fat_core/range.rb', line 32 def contiguous?(other) left_contiguous?(other) || right_contiguous?(other) end |
#difference(other) ⇒ Object Also known as: -
The difference method, -, removes the overlapping part of the other argument from self. Because in the case where self is a superset of the other range, this will result in the difference being two non-contiguous ranges, this returns an array of ranges. If there is no overlap or if self is a subset of the other range, return an array of self
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/fat_core/range.rb', line 74 def difference(other) unless max.respond_to?(:succ) && min.respond_to?(:pred) && other.max.respond_to?(:succ) && other.min.respond_to?(:pred) raise "Range difference operation requires objects have pred and succ methods" end # return [self] unless self.overlaps?(other) if subset_of?(other) # (4..7) - (0..10) [] elsif proper_superset_of?(other) # (4..7) - (5..5) -> [(4..4), (6..7)] [(min..other.min.pred), (other.max.succ..max)] elsif overlaps?(other) && other.min <= min # (4..7) - (2..5) -> (6..7) [(other.max.succ .. max)] elsif overlaps?(other) && other.max >= max # (4..7) - (6..10) -> (4..5) [(min .. other.min.pred)] else [ self ] end end |
#gaps(ranges) ⇒ Object
If this range is not spanned by the ranges collectively, return an array of ranges representing the gaps in coverage. Otherwise return an empty array.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/fat_core/range.rb', line 138 def gaps(ranges) if ranges.empty? [self.clone] elsif spanned_by?(ranges) [] else ranges = ranges.sort_by {|r| r.min} gaps = [] cur_point = min ranges.each do |rr| break if rr.min > max if rr.min > cur_point start_point = cur_point end_point = rr.min.pred gaps << (start_point..end_point) cur_point = rr.max.succ elsif rr.max >= cur_point cur_point = rr.max.succ end end if cur_point < max gaps << (cur_point..max) end gaps end end |
#has_overlaps_within?(ranges) ⇒ Boolean
Return whether any of the ranges that are within self overlap one another
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/fat_core/range.rb', line 100 def has_overlaps_within?(ranges) result = false unless ranges.empty? ranges.each do |r1| next unless overlaps?(r1) result = ranges.any? do |r2| r1.object_id != r2.object_id && overlaps?(r2) && r1.overlaps?(r2) end return true if result end end result end |
#intersection(other) ⇒ Object Also known as: &
57 58 59 60 |
# File 'lib/fat_core/range.rb', line 57 def intersection(other) return nil unless self.overlaps?(other) ([self.min, other.min].max..[self.max, other.max].min) end |
#join(other) ⇒ Object
Return a range that concatenates this range with other; return nil if the ranges are not contiguous.
4 5 6 7 8 9 10 11 12 |
# File 'lib/fat_core/range.rb', line 4 def join(other) if left_contiguous?(other) Range.new(min, other.max) elsif right_contiguous?(other) Range.new(other.min, max) else nil end end |
#left_contiguous?(other) ⇒ Boolean
Is self on the left of and contiguous to other?
15 16 17 18 19 20 21 |
# File 'lib/fat_core/range.rb', line 15 def left_contiguous?(other) if max.respond_to?(:succ) max.succ == other.min else max == other.min end end |
#overlaps(ranges) ⇒ Object
Similar to gaps, but within this range return the /overlaps/ among the given ranges. If there are no overlaps, return an empty array. Don’t consider overlaps in the ranges that occur outside of self.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/fat_core/range.rb', line 168 def overlaps(ranges) if ranges.empty? || spanned_by?(ranges) [] else ranges = ranges.sort_by {|r| r.min} overlaps = [] cur_point = nil ranges.each do |rr| # Skip ranges outside of self next if rr.max < min || rr.min > max # Initialize cur_point to max of first range if cur_point.nil? cur_point = rr.max next end # We are on the second or later range if rr.min < cur_point start_point = rr.min end_point = cur_point overlaps << (start_point..end_point) end cur_point = rr.max end overlaps end end |
#overlaps?(other) ⇒ Boolean
52 53 54 55 |
# File 'lib/fat_core/range.rb', line 52 def overlaps?(other) (cover?(other.min) || cover?(other.max) || other.cover?(min) || other.cover?(max)) end |
#proper_subset_of?(other) ⇒ Boolean
40 41 42 |
# File 'lib/fat_core/range.rb', line 40 def proper_subset_of?(other) min > other.min && max < other.max end |
#proper_superset_of?(other) ⇒ Boolean
48 49 50 |
# File 'lib/fat_core/range.rb', line 48 def proper_superset_of?(other) min < other.min && max > other.max end |
#right_contiguous?(other) ⇒ Boolean
Is self on the right of and contiguous to other?
24 25 26 27 28 29 30 |
# File 'lib/fat_core/range.rb', line 24 def right_contiguous?(other) if other.max.respond_to?(:succ) other.max.succ == min else other.max == min end end |
#spanned_by?(ranges) ⇒ Boolean
Return true if the given ranges collectively cover this range without overlaps.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/fat_core/range.rb', line 118 def spanned_by?(ranges) joined_range = nil ranges.sort_by {|r| r.min}.each do |r| unless joined_range joined_range = r next end joined_range = joined_range.join(r) break if joined_range.nil? end if !joined_range.nil? joined_range.min <= min && joined_range.max >= max else false end end |
#subset_of?(other) ⇒ Boolean
36 37 38 |
# File 'lib/fat_core/range.rb', line 36 def subset_of?(other) min >= other.min && max <= other.max end |
#superset_of?(other) ⇒ Boolean
44 45 46 |
# File 'lib/fat_core/range.rb', line 44 def superset_of?(other) min <= other.min && max >= other.max end |
#tex_quote ⇒ Object
Allow erb documents can directly interpolate ranges
196 197 198 |
# File 'lib/fat_core/range.rb', line 196 def tex_quote to_s end |
#union(other) ⇒ Object Also known as: +
63 64 65 66 |
# File 'lib/fat_core/range.rb', line 63 def union(other) return nil unless self.overlaps?(other) || self.contiguous?(other) ([self.min, other.min].min..[self.max, other.max].max) end |