Class: BetterRanges::SparseRange
- Inherits:
-
Object
- Object
- BetterRanges::SparseRange
- Includes:
- Enumerable
- Defined in:
- lib/better_ranges/sparse_range.rb
Instance Method Summary collapse
- #&(x) ⇒ Object (also: #intersect)
- #-(x) ⇒ Object (also: #minus, #difference)
- #<<(x) ⇒ Object (also: #add)
- #==(x) ⇒ Object (also: #eql?)
- #each(&block) ⇒ Object
- #empty? ⇒ Boolean
-
#hash ⇒ Object
TODO: Calculate hash without creating the temp array.
- #include?(x) ⇒ Boolean (also: #cover?, #===)
-
#initialize(*data) ⇒ SparseRange
constructor
A new instance of SparseRange.
- #inspect ⇒ Object
- #last ⇒ Object
- #size ⇒ Object
- #sparse_each(&block) ⇒ Object
- #step(num = 1, &block) ⇒ Object
- #|(x) ⇒ Object (also: #+, #union)
Constructor Details
#initialize(*data) ⇒ SparseRange
Returns a new instance of SparseRange.
5 6 7 8 9 10 11 12 13 14 |
# File 'lib/better_ranges/sparse_range.rb', line 5 def initialize(*data) @data = [*data].map! do |x| if x.is_a?(Enumerable) return nil if x.none? return x.data.clone if x.is_a?(SparseRange) end x end optimize end |
Instance Method Details
#&(x) ⇒ Object Also known as: intersect
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/better_ranges/sparse_range.rb', line 87 def &(x) intersect = SparseRange.new intersect_data = intersect.data i = 0 next_val = lambda do throw :done unless i < @data.length v = read_val(@data[i]) i += 1 v end catch(:done) do other = (x.is_a?(SparseRange) ? x : SparseRange.new(x)).data start, finish = next_val.call other.each do |r| other_start, other_finish = read_val(r) start, finish = next_val.call while finish < other_start until other_finish < start first = [start, other_start].max last = [finish, other_finish].min intersect_data << write_val(first, last) start = last.succ if start < other_finish other_start = start start, finish = next_val.call end end end end intersect end |
#-(x) ⇒ Object Also known as: minus, difference
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/better_ranges/sparse_range.rb', line 50 def -(x) diff = SparseRange.new diff_data = diff.data i = 0 next_val = lambda do throw :done unless i < @data.length v = read_val(@data[i]) i += 1 v end catch(:done) do other = (x.is_a?(SparseRange) ? x : SparseRange.new(x)).data start, finish = next_val.call other.each do |r| other_start, other_finish = read_val(r) while finish < other_start diff_data << write_val(start, finish) start, finish = next_val.call end next if other_finish < start diff_data << (start.succ == other_start ? start : (start...other_start)) if start < other_start start = other_finish.succ start, finish = next_val.call if start > finish end diff_data << write_val(start, finish) loop { diff_data << write_val(*next_val.call) } end diff end |
#<<(x) ⇒ Object Also known as: add
125 126 127 128 129 130 |
# File 'lib/better_ranges/sparse_range.rb', line 125 def <<(x) @data << [*(x.is_a?(SparseRange) ? x.data : x)] optimize self end |
#==(x) ⇒ Object Also known as: eql?
150 151 152 153 154 155 156 157 158 |
# File 'lib/better_ranges/sparse_range.rb', line 150 def ==(x) other = (x.is_a?(SparseRange) ? x : SparseRange.new(x)).data i = 0 (@data.length == other.length) && @data.all? do |e| o = other[i] i += 1 (e == o) || (read_val(e) == read_val(o)) end end |
#each(&block) ⇒ Object
16 17 18 19 20 21 22 |
# File 'lib/better_ranges/sparse_range.rb', line 16 def each(&block) Enumerator.new do |yielder| @data.each do |r| yield_each(r) { |x| yielder.yield x } end end.each(&block) end |
#empty? ⇒ Boolean
142 143 144 |
# File 'lib/better_ranges/sparse_range.rb', line 142 def empty? @data.empty? || size == 0 end |
#hash ⇒ Object
TODO: Calculate hash without creating the temp array
161 162 163 |
# File 'lib/better_ranges/sparse_range.rb', line 161 def hash @data.map(&method(:read_val)).hash end |
#include?(x) ⇒ Boolean Also known as: cover?, ===
136 137 138 139 140 |
# File 'lib/better_ranges/sparse_range.rb', line 136 def include?(x) @data.any? do |r| r.is_a?(Range) ? r.include?(x) : x == r end end |
#inspect ⇒ Object
132 133 134 |
# File 'lib/better_ranges/sparse_range.rb', line 132 def inspect @data.inspect end |
#last ⇒ Object
42 43 44 |
# File 'lib/better_ranges/sparse_range.rb', line 42 def last read_val(@data.last).last end |
#size ⇒ Object
146 147 148 |
# File 'lib/better_ranges/sparse_range.rb', line 146 def size @data.reduce(0) { |a, e| a + (e.is_a?(Range) ? e.count : 1) } end |
#sparse_each(&block) ⇒ Object
24 25 26 27 28 |
# File 'lib/better_ranges/sparse_range.rb', line 24 def sparse_each(&block) @data.each do |x| x.is_a?(Range) ? x : (x..x) end end |
#step(num = 1, &block) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/better_ranges/sparse_range.rb', line 30 def step(num = 1, &block) i = 0 Enumerator.new do |yielder| @data.each do |r| yield_each(r) do |x| yielder.yield x if (i % num) == 0 i += 1 end end end.each(&block) end |
#|(x) ⇒ Object Also known as: +, union
46 47 48 |
# File 'lib/better_ranges/sparse_range.rb', line 46 def |(x) SparseRange.new(@data, *x) end |