Module: Lab42::Stream::Enumerable
- Included in:
- Lab42::Stream
- Defined in:
- lib/lab42/stream/enumerable.rb
Instance Method Summary collapse
- #__drop_while__(bhv) ⇒ Object
- #__filter__(stream, a_proc) ⇒ Object
- #__flatmap__(a_proc) ⇒ Object
- #__flatmap_with_each__(a_proc, rest_of_enum = []) ⇒ Object
- #__inject__(agg, a_proc) ⇒ Object
- #__inject_while__(ival, cond, red) ⇒ Object
- #__lazy_take__(n) ⇒ Object
- #__lazy_take_until__(bhv) ⇒ Object
- #__lazy_take_while__(bhv) ⇒ Object
- #__map__(prc) ⇒ Object
- #__scan__(initial, beh) ⇒ Object
- #__take_while__(bhv) ⇒ Object
- #__zip__(streams) ⇒ Object
- #drop_until(*bhv, &blk) ⇒ Object
- #drop_while(*bhv, &blk) ⇒ Object
- #each ⇒ Object
- #each_without_loops ⇒ Object
- #filter(*args, &blk) ⇒ Object
- #flatmap(*args, &blk) ⇒ Object
- #flatmap_with_each(*args, &blk) ⇒ Object
- #force_all(cache = {}) ⇒ Object
- #inject(agg, *red, &reducer) ⇒ Object
- #lazy_take(n = 1) ⇒ Object
- #lazy_take_until(*bhv, &blk) ⇒ Object
- #lazy_take_while(*bhv, &blk) ⇒ Object
- #make_cyclic ⇒ Object
- #map(*args, &blk) ⇒ Object
- #reduce(red = nil, &reducer) ⇒ Object
- #reduce_while(cond, red = nil, &reducer) ⇒ Object
- #reject(*args, &blk) ⇒ Object
- #scan(initial, *args, &blk) ⇒ Object
- #scan1(*args, &blk) ⇒ Object
- #take(n = 1) ⇒ Object
- #take_until(*bhv, &blk) ⇒ Object
- #take_while(*bhv, &blk) ⇒ Object
- #to_a ⇒ Object (also: #entries)
- #zip(*other_streamables) ⇒ Object
- #zip_as_ary(*other_streamables) ⇒ Object
Instance Method Details
#__drop_while__(bhv) ⇒ Object
21 22 23 24 25 26 27 28 |
# File 'lib/lab42/stream/enumerable.rb', line 21 def __drop_while__ bhv s = self loop do return s unless bhv.(s.head) s = s.tail end empty_stream end |
#__filter__(stream, a_proc) ⇒ Object
245 246 247 248 249 250 251 |
# File 'lib/lab42/stream/enumerable.rb', line 245 def __filter__ stream, a_proc loop do return stream if stream.empty? return cons_stream( stream.head ){ __filter__ stream.tail, a_proc } if a_proc.( stream.head ) stream = stream.tail end end |
#__flatmap__(a_proc) ⇒ Object
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/lab42/stream/enumerable.rb', line 121 def __flatmap__ a_proc hh = a_proc.( head ) raise ArgumentError, "flatmap can only map on streams, use flatmap_with_each to map over streams and enumerables" unless Lab42::Stream === hh if hh.empty? tail.__flatmap__ a_proc else cons_stream( hh.head ){ hh.tail + tail.__flatmap__( a_proc ) } end end |
#__flatmap_with_each__(a_proc, rest_of_enum = []) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/lab42/stream/enumerable.rb', line 136 def __flatmap_with_each__ a_proc, rest_of_enum = [] # Process expanded values return cons_stream( rest_of_enum.first ){ __flatmap_with_each__ a_proc, rest_of_enum.drop( 1 ) } unless rest_of_enum.empty? # Map a scalar value hh = a_proc.( head ) return cons_stream( hh ){ tail.__flatmap_with_each__ a_proc } unless hh.respond_to? :each # Start a new expansion... # ... consider an empty expansion return tail.__flatmap__ a_proc if hh.empty? # ... expand values cons_stream( hh.first ){ tail.__flatmap_with_each__( a_proc, hh.drop( 1 ) ) } end |
#__inject__(agg, a_proc) ⇒ Object
253 254 255 256 |
# File 'lib/lab42/stream/enumerable.rb', line 253 def __inject__ agg, a_proc new_agg = a_proc.(agg, head) tail.__inject__ new_agg, a_proc end |
#__inject_while__(ival, cond, red) ⇒ Object
258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/lab42/stream/enumerable.rb', line 258 def __inject_while__ ival, cond, red raise ConstraintError unless cond.(ival) s = self loop do new_val = red.(ival, s.head) return ival unless cond.(new_val) ival = new_val s = s.tail return ival if s.empty? end end |
#__lazy_take__(n) ⇒ Object
71 72 73 74 |
# File 'lib/lab42/stream/enumerable.rb', line 71 def __lazy_take__ n return empty_stream if n.zero? cons_stream( head ){ tail.__lazy_take__ n.pred } end |
#__lazy_take_until__(bhv) ⇒ Object
81 82 83 84 85 86 |
# File 'lib/lab42/stream/enumerable.rb', line 81 def __lazy_take_until__ bhv return empty_stream if bhv.(head) cons_stream( head ){ tail.__lazy_take_until__ bhv } end |
#__lazy_take_while__(bhv) ⇒ Object
93 94 95 96 97 98 |
# File 'lib/lab42/stream/enumerable.rb', line 93 def __lazy_take_while__ bhv return empty_stream unless bhv.(head) cons_stream( head ){ tail.__lazy_take_while__ bhv } end |
#__map__(prc) ⇒ Object
206 207 208 |
# File 'lib/lab42/stream/enumerable.rb', line 206 def __map__ prc cons_stream( prc.(head) ){ tail.__map__ prc } end |
#__scan__(initial, beh) ⇒ Object
165 166 167 168 |
# File 'lib/lab42/stream/enumerable.rb', line 165 def __scan__ initial, beh h = beh.(initial, head) cons_stream( h ){ tail.__scan__ h, beh } end |
#__take_while__(bhv) ⇒ Object
180 181 182 183 184 185 186 187 |
# File 'lib/lab42/stream/enumerable.rb', line 180 def __take_while__ bhv x = [] each do | ele | return x unless bhv.( ele ) x << ele end x end |
#__zip__(streams) ⇒ Object
239 240 241 242 243 |
# File 'lib/lab42/stream/enumerable.rb', line 239 def __zip__ streams cons_stream( [head] + streams.map(&:head) ){ tail.__zip__ streams.map(&:tail) } end |
#drop_until(*bhv, &blk) ⇒ Object
10 11 12 13 |
# File 'lib/lab42/stream/enumerable.rb', line 10 def drop_until *bhv, &blk bhv = Behavior.make( *bhv, &blk ) __drop_while__ bhv.not end |
#drop_while(*bhv, &blk) ⇒ Object
15 16 17 18 |
# File 'lib/lab42/stream/enumerable.rb', line 15 def drop_while *bhv, &blk bhv = Behavior.make( *bhv, &blk ) __drop_while__ bhv end |
#each ⇒ Object
30 31 32 33 34 35 36 37 |
# File 'lib/lab42/stream/enumerable.rb', line 30 def each t = self loop do return if t.empty? yield t.head t = t.tail end end |
#each_without_loops ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/lab42/stream/enumerable.rb', line 39 def each_without_loops visited = {} t = self loop do h = t.head yield h visited[ t.object_id ] = true t = t.tail return if visited[t.object_id] end end |
#filter(*args, &blk) ⇒ Object
109 110 111 |
# File 'lib/lab42/stream/enumerable.rb', line 109 def filter *args, &blk __filter__ self, Behavior.make( *args, &blk ) end |
#flatmap(*args, &blk) ⇒ Object
117 118 119 |
# File 'lib/lab42/stream/enumerable.rb', line 117 def flatmap *args, &blk __flatmap__ Behavior.make( *args, &blk ) end |
#flatmap_with_each(*args, &blk) ⇒ Object
132 133 134 |
# File 'lib/lab42/stream/enumerable.rb', line 132 def flatmap_with_each *args, &blk __flatmap_with_each__ Behavior.make( *args, &blk ) end |
#force_all(cache = {}) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/lab42/stream/enumerable.rb', line 51 def force_all cache={} x = [] each_without_loops do | ele | if self.class === ele if ! cache[ele.object_id] cache[ele.object_id] = true x << ele.force_all( cache ) end else x << ele end end x end |
#inject(agg, *red, &reducer) ⇒ Object
105 106 107 |
# File 'lib/lab42/stream/enumerable.rb', line 105 def inject agg, *red, &reducer __inject__ agg, Behavior.make( *red, &reducer ) end |
#lazy_take(n = 1) ⇒ Object
66 67 68 69 |
# File 'lib/lab42/stream/enumerable.rb', line 66 def lazy_take n=1 raise ArgumentError, "need a non negative Integer" if !(Integer === n) || n < 0 __lazy_take__ n end |
#lazy_take_until(*bhv, &blk) ⇒ Object
76 77 78 79 |
# File 'lib/lab42/stream/enumerable.rb', line 76 def lazy_take_until *bhv, &blk bhv = Behavior.make( *bhv, &blk ) __lazy_take_until__ bhv end |
#lazy_take_while(*bhv, &blk) ⇒ Object
88 89 90 91 |
# File 'lib/lab42/stream/enumerable.rb', line 88 def lazy_take_while *bhv, &blk bhv = Behavior.make( *bhv, &blk ) __lazy_take_while__ bhv end |
#make_cyclic ⇒ Object
195 196 197 198 199 |
# File 'lib/lab42/stream/enumerable.rb', line 195 def make_cyclic cons_stream( head ){ tail.append( make_cyclic ) } end |
#map(*args, &blk) ⇒ Object
201 202 203 204 |
# File 'lib/lab42/stream/enumerable.rb', line 201 def map *args, &blk raise ArgumentError, "use either a block or arguments" if args.empty? && !blk || !args.empty? && blk __map__ Behavior.make( *args, &blk ) end |
#reduce(red = nil, &reducer) ⇒ Object
100 101 102 103 |
# File 'lib/lab42/stream/enumerable.rb', line 100 def reduce red=nil, &reducer red = Behavior.make( red, &reducer) tail.__inject__ head, red end |
#reduce_while(cond, red = nil, &reducer) ⇒ Object
211 212 213 214 |
# File 'lib/lab42/stream/enumerable.rb', line 211 def reduce_while cond, red=nil, &reducer red ||= reducer tail.__inject_while__ head, cond, red end |
#reject(*args, &blk) ⇒ Object
113 114 115 |
# File 'lib/lab42/stream/enumerable.rb', line 113 def reject *args, &blk __filter__ self, Behavior.make( *args, &blk ).not end |
#scan(initial, *args, &blk) ⇒ Object
154 155 156 157 158 159 |
# File 'lib/lab42/stream/enumerable.rb', line 154 def scan initial, *args, &blk cons_stream initial do __scan__ initial, Behavior.make( *args, &blk ) end.tap{ |r| } end |
#scan1(*args, &blk) ⇒ Object
161 162 163 |
# File 'lib/lab42/stream/enumerable.rb', line 161 def scan1 *args, &blk tail.scan( head, *args, &blk ) end |
#take(n = 1) ⇒ Object
216 217 218 219 220 221 222 223 224 225 |
# File 'lib/lab42/stream/enumerable.rb', line 216 def take n=1 raise ArgumentError, "need a non negative Integer" if !(Integer === n) || n < 0 x = [] each do | ele | return x if n.zero? n -= 1 x << ele end x end |
#take_until(*bhv, &blk) ⇒ Object
170 171 172 173 |
# File 'lib/lab42/stream/enumerable.rb', line 170 def take_until *bhv, &blk bhv = Behavior.make( *bhv, &blk ) __take_while__ bhv.not end |
#take_while(*bhv, &blk) ⇒ Object
175 176 177 178 |
# File 'lib/lab42/stream/enumerable.rb', line 175 def take_while *bhv, &blk bhv = Behavior.make( *bhv, &blk ) __take_while__ bhv end |
#to_a ⇒ Object Also known as: entries
189 190 191 |
# File 'lib/lab42/stream/enumerable.rb', line 189 def to_a take_while Behavior.const( true ) end |
#zip(*other_streamables) ⇒ Object
227 228 229 230 231 232 |
# File 'lib/lab42/stream/enumerable.rb', line 227 def zip *other_streamables streams = other_streamables.map{ |s| self.class === s ? s : s.to_stream } __zip__ streams end |
#zip_as_ary(*other_streamables) ⇒ Object
234 235 236 237 |
# File 'lib/lab42/stream/enumerable.rb', line 234 def zip_as_ary *other_streamables zip( *other_streamables ) .map( &:entries ) end |