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
30 31 32 |
# File 'lib/fat_core/range.rb', line 30 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
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/fat_core/range.rb', line 72 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 requires objects have pred and succ methods' end 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.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/fat_core/range.rb', line 135 def gaps(ranges) if ranges.empty? [clone] elsif spanned_by?(ranges) [] else ranges = ranges.sort_by(&: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 gaps << (cur_point..max) if cur_point <= max gaps end end |
#has_overlaps_within?(ranges) ⇒ Boolean
Return whether any of the ranges that are within self overlap one another
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/fat_core/range.rb', line 97 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: &
55 56 57 58 |
# File 'lib/fat_core/range.rb', line 55 def intersection(other) return nil unless overlaps?(other) ([min, other.min].max..[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 |
# 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) end end |
#left_contiguous?(other) ⇒ Boolean
Is self on the left of and contiguous to other?
13 14 15 16 17 18 19 |
# File 'lib/fat_core/range.rb', line 13 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.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/fat_core/range.rb', line 163 def overlaps(ranges) if ranges.empty? || spanned_by?(ranges) [] else ranges = ranges.sort_by(&: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
50 51 52 53 |
# File 'lib/fat_core/range.rb', line 50 def overlaps?(other) (cover?(other.min) || cover?(other.max) || other.cover?(min) || other.cover?(max)) end |
#proper_subset_of?(other) ⇒ Boolean
38 39 40 |
# File 'lib/fat_core/range.rb', line 38 def proper_subset_of?(other) min > other.min && max < other.max end |
#proper_superset_of?(other) ⇒ Boolean
46 47 48 |
# File 'lib/fat_core/range.rb', line 46 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?
22 23 24 25 26 27 28 |
# File 'lib/fat_core/range.rb', line 22 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.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/fat_core/range.rb', line 115 def spanned_by?(ranges) joined_range = nil ranges.sort_by(&: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
34 35 36 |
# File 'lib/fat_core/range.rb', line 34 def subset_of?(other) min >= other.min && max <= other.max end |
#superset_of?(other) ⇒ Boolean
42 43 44 |
# File 'lib/fat_core/range.rb', line 42 def superset_of?(other) min <= other.min && max >= other.max end |
#tex_quote ⇒ Object
Allow erb documents can directly interpolate ranges
191 192 193 |
# File 'lib/fat_core/range.rb', line 191 def tex_quote to_s end |
#union(other) ⇒ Object Also known as: +
61 62 63 64 |
# File 'lib/fat_core/range.rb', line 61 def union(other) return nil unless overlaps?(other) || contiguous?(other) ([min, other.min].min..[max, other.max].max) end |