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
247 248 249 250 251 252 253 |
# File 'lib/lab42/stream/enumerable.rb', line 247 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
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/lab42/stream/enumerable.rb', line 121 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
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
255 256 257 258 |
# File 'lib/lab42/stream/enumerable.rb', line 255 def __inject__ agg, a_proc new_agg = a_proc.(agg, head) tail.__inject__ new_agg, a_proc end |
#__inject_while__(ival, cond, red) ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/lab42/stream/enumerable.rb', line 260 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
208 209 210 |
# File 'lib/lab42/stream/enumerable.rb', line 208 def __map__ prc cons_stream( prc.(head) ){ tail.__map__ prc } end |
#__scan__(initial, beh) ⇒ Object
167 168 169 170 |
# File 'lib/lab42/stream/enumerable.rb', line 167 def __scan__ initial, beh h = beh.(initial, head) cons_stream( h ){ tail.__scan__ h, beh } end |
#__zip__(streams) ⇒ Object
241 242 243 244 245 |
# File 'lib/lab42/stream/enumerable.rb', line 241 def __zip__ streams cons_stream( [head] + streams.map(:head) ){ tail.__zip__ streams.map(:tail) } end |
#drop_until(*bhv, &blk) ⇒ Object
9 10 11 12 13 14 15 16 17 |
# File 'lib/lab42/stream/enumerable.rb', line 9 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
21 22 23 24 25 26 27 28 29 |
# File 'lib/lab42/stream/enumerable.rb', line 21 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
31 32 33 34 35 36 37 |
# File 'lib/lab42/stream/enumerable.rb', line 31 def each t = self loop do 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__ blk.make_behavior( *args ) end |
#flatmap(*args, &blk) ⇒ Object
117 118 119 |
# File 'lib/lab42/stream/enumerable.rb', line 117 def flatmap *args, &blk __flatmap__ blk.make_behavior( *args ) 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__ blk.make_behavior( *args ) 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, reducer.make_behavior( *red ) 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 Fixnum" if !(Fixnum === 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 = blk.make_behavior( *bhv ) __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 = blk.make_behavior( *bhv ) __lazy_take_while__ bhv end |
#make_cyclic ⇒ Object
196 197 198 199 200 |
# File 'lib/lab42/stream/enumerable.rb', line 196 def make_cyclic cons_stream( head ){ tail.append( make_cyclic ) } end |
#map(*args, &blk) ⇒ Object
202 203 204 205 206 |
# File 'lib/lab42/stream/enumerable.rb', line 202 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
100 101 102 103 |
# File 'lib/lab42/stream/enumerable.rb', line 100 def reduce red=nil, &reducer red = reducer.make_behavior( red ) tail.__inject__ head, red end |
#reduce_while(cond, red = nil, &reducer) ⇒ Object
213 214 215 216 |
# File 'lib/lab42/stream/enumerable.rb', line 213 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__ blk.make_behavior( *args ).not end |
#scan(initial, *args, &blk) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/lab42/stream/enumerable.rb', line 154 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
163 164 165 |
# File 'lib/lab42/stream/enumerable.rb', line 163 def scan1 *args, &blk tail.scan( head, *args, &blk ) end |
#take(n = 1) ⇒ Object
218 219 220 221 222 223 224 225 226 227 |
# File 'lib/lab42/stream/enumerable.rb', line 218 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
172 173 174 175 176 177 178 179 180 |
# File 'lib/lab42/stream/enumerable.rb', line 172 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
181 182 183 184 185 186 187 188 189 |
# File 'lib/lab42/stream/enumerable.rb', line 181 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
191 192 193 |
# File 'lib/lab42/stream/enumerable.rb', line 191 def to_a take_while :true end |
#zip(*other_streamables) ⇒ Object
229 230 231 232 233 234 |
# File 'lib/lab42/stream/enumerable.rb', line 229 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
236 237 238 239 |
# File 'lib/lab42/stream/enumerable.rb', line 236 def zip_as_ary *other_streamables zip( *other_streamables ) .map( &:entries ) end |