Module: Lab42::Stream::Enumerable
- Included in:
- Lab42::Stream
- Defined in:
- lib/lab42/stream/enumerable.rb
Instance Method Summary collapse
- #__filter__(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
- #__zip__(streams) ⇒ Object
- #drop_until(*bhv, &blk) ⇒ Object
-
#drop_while(*bhv, &blk) ⇒ Object
N.B.
- #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
#__filter__(a_proc) ⇒ Object
249 250 251 252 253 254 255 |
# File 'lib/lab42/stream/enumerable.rb', line 249 def __filter__ a_proc if a_proc.( head ) cons_stream( head ){ tail.__filter__ a_proc } else tail.__filter__ a_proc end end |
#__flatmap__(a_proc) ⇒ Object
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/lab42/stream/enumerable.rb', line 123 def __flatmap__ a_proc # require 'pry' # binding.pry hh = a_proc.( head ) 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
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/lab42/stream/enumerable.rb', line 138 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
257 258 259 260 |
# File 'lib/lab42/stream/enumerable.rb', line 257 def __inject__ agg, a_proc new_agg = a_proc.(agg, head) tail.__inject__ new_agg, a_proc end |
#__inject_while__(ival, cond, red) ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/lab42/stream/enumerable.rb', line 262 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
73 74 75 76 |
# File 'lib/lab42/stream/enumerable.rb', line 73 def __lazy_take__ n return empty_stream if n.zero? cons_stream( head ){ tail.__lazy_take__ n.pred } end |
#__lazy_take_until__(bhv) ⇒ Object
83 84 85 86 87 88 |
# File 'lib/lab42/stream/enumerable.rb', line 83 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
95 96 97 98 99 100 |
# File 'lib/lab42/stream/enumerable.rb', line 95 def __lazy_take_while__ bhv return empty_stream unless bhv.(head) cons_stream( head ){ tail.__lazy_take_while__ bhv } end |
#__map__(prc) ⇒ Object
210 211 212 |
# File 'lib/lab42/stream/enumerable.rb', line 210 def __map__ prc cons_stream( prc.(head) ){ tail.__map__ prc } end |
#__scan__(initial, beh) ⇒ Object
169 170 171 172 |
# File 'lib/lab42/stream/enumerable.rb', line 169 def __scan__ initial, beh h = beh.(initial, head) cons_stream( h ){ tail.__scan__ h, beh } end |
#__zip__(streams) ⇒ Object
243 244 245 246 247 |
# File 'lib/lab42/stream/enumerable.rb', line 243 def __zip__ streams cons_stream( [head] + streams.map(:head) ){ tail.__zip__ streams.map(:tail) } end |
#drop_until(*bhv, &blk) ⇒ Object
11 12 13 14 15 16 17 18 19 |
# File 'lib/lab42/stream/enumerable.rb', line 11 def drop_until *bhv, &blk bhv = blk.make_behavior( *bhv ) s = self loop do return s if bhv.(s.head) s = s.tail end empty_stream end |
#drop_while(*bhv, &blk) ⇒ Object
N.B. Not implemented as drop_until( bhv.not ) for performance reasons
23 24 25 26 27 28 29 30 31 |
# File 'lib/lab42/stream/enumerable.rb', line 23 def drop_while *bhv, &blk bhv = blk.make_behavior( *bhv ) s = self loop do return s unless bhv.(s.head) s = s.tail end empty_stream end |
#each ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/lab42/stream/enumerable.rb', line 33 def each t = self loop do yield t.head t = t.tail end end |
#each_without_loops ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/lab42/stream/enumerable.rb', line 41 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
111 112 113 |
# File 'lib/lab42/stream/enumerable.rb', line 111 def filter *args, &blk __filter__ blk.make_behavior( *args ) end |
#flatmap(*args, &blk) ⇒ Object
119 120 121 |
# File 'lib/lab42/stream/enumerable.rb', line 119 def flatmap *args, &blk __flatmap__ blk.make_behavior( *args ) end |
#flatmap_with_each(*args, &blk) ⇒ Object
134 135 136 |
# File 'lib/lab42/stream/enumerable.rb', line 134 def flatmap_with_each *args, &blk __flatmap_with_each__ blk.make_behavior( *args ) end |
#force_all(cache = {}) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/lab42/stream/enumerable.rb', line 53 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
107 108 109 |
# File 'lib/lab42/stream/enumerable.rb', line 107 def inject agg, *red, &reducer __inject__ agg, reducer.make_behavior( *red ) end |
#lazy_take(n = 1) ⇒ Object
68 69 70 71 |
# File 'lib/lab42/stream/enumerable.rb', line 68 def lazy_take n=1 raise ArgumentError, "need a non negative Fixnum" if !(Fixnum === n) || n < 0 __lazy_take__ n end |
#lazy_take_until(*bhv, &blk) ⇒ Object
78 79 80 81 |
# File 'lib/lab42/stream/enumerable.rb', line 78 def lazy_take_until *bhv, &blk bhv = blk.make_behavior( *bhv ) __lazy_take_until__ bhv end |
#lazy_take_while(*bhv, &blk) ⇒ Object
90 91 92 93 |
# File 'lib/lab42/stream/enumerable.rb', line 90 def lazy_take_while *bhv, &blk bhv = blk.make_behavior( *bhv ) __lazy_take_while__ bhv end |
#make_cyclic ⇒ Object
198 199 200 201 202 |
# File 'lib/lab42/stream/enumerable.rb', line 198 def make_cyclic cons_stream( head ){ tail.append( make_cyclic ) } end |
#map(*args, &blk) ⇒ Object
204 205 206 207 208 |
# File 'lib/lab42/stream/enumerable.rb', line 204 def map *args, &blk # TODO: Get this check and a factory to create a proc for this into core/fn raise ArgumentError, "use either a block or arguments" if args.empty? && !blk || !args.empty? && blk __map__ blk.make_behavior( *args ) end |
#reduce(red = nil, &reducer) ⇒ Object
102 103 104 105 |
# File 'lib/lab42/stream/enumerable.rb', line 102 def reduce red=nil, &reducer red = reducer.make_behavior( red ) tail.__inject__ head, red end |
#reduce_while(cond, red = nil, &reducer) ⇒ Object
215 216 217 218 |
# File 'lib/lab42/stream/enumerable.rb', line 215 def reduce_while cond, red=nil, &reducer red ||= reducer tail.__inject_while__ head, cond, red end |
#reject(*args, &blk) ⇒ Object
115 116 117 |
# File 'lib/lab42/stream/enumerable.rb', line 115 def reject *args, &blk __filter__ blk.make_behavior( *args ).not end |
#scan(initial, *args, &blk) ⇒ Object
156 157 158 159 160 161 162 163 |
# File 'lib/lab42/stream/enumerable.rb', line 156 def scan initial, *args, &blk cons_stream initial do __scan__ initial, blk.make_behavior( *args ) end.tap{ |r| # require 'pry' # binding.pry } end |
#scan1(*args, &blk) ⇒ Object
165 166 167 |
# File 'lib/lab42/stream/enumerable.rb', line 165 def scan1 *args, &blk tail.scan( head, *args, &blk ) end |
#take(n = 1) ⇒ Object
220 221 222 223 224 225 226 227 228 229 |
# File 'lib/lab42/stream/enumerable.rb', line 220 def take n=1 raise ArgumentError, "need a non negative Fixnum" if !(Fixnum === n) || n < 0 x = [] each do | ele | return x if n.zero? n -= 1 x << ele end x end |
#take_until(*bhv, &blk) ⇒ Object
174 175 176 177 178 179 180 181 182 |
# File 'lib/lab42/stream/enumerable.rb', line 174 def take_until *bhv, &blk bhv = blk.make_behavior( *bhv ) x = [] each do | ele | return x if bhv.( ele ) x << ele end x end |
#take_while(*bhv, &blk) ⇒ Object
183 184 185 186 187 188 189 190 191 |
# File 'lib/lab42/stream/enumerable.rb', line 183 def take_while *bhv, &blk bhv = blk.make_behavior( *bhv ) x = [] each do | ele | return x unless bhv.( ele ) x << ele end x end |
#to_a ⇒ Object Also known as: entries
193 194 195 |
# File 'lib/lab42/stream/enumerable.rb', line 193 def to_a take_while :true end |
#zip(*other_streamables) ⇒ Object
231 232 233 234 235 236 |
# File 'lib/lab42/stream/enumerable.rb', line 231 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
238 239 240 241 |
# File 'lib/lab42/stream/enumerable.rb', line 238 def zip_as_ary *other_streamables zip( *other_streamables ) .map( &:entries ) end |