lookaround-enumerable 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0f7147396b91cb815e80a4c1e15db38736b9900e84a0f7e07f12e4564c54dfe5
4
+ data.tar.gz: b55b5655cbb962ccb2188a4a4346230122cddd220fe81490fed0d1cb5aee1210
5
+ SHA512:
6
+ metadata.gz: b65d153993c566a985d54e67d9c0b51a7a2dc2bf81cb04060166b8b6c2434eb4f1d85942194cdbad7314b5f07dd8d2309d0823e16a049cad1963f49eb7b61f10
7
+ data.tar.gz: 3a4298e88e9135a967e1780644460b9b2f59cf1aaa7bb92a4c7dfe2d126d2ee6cf3e0603e0a464e4e76a525554d6eac1dd6b1574d8fd97d21069990434195e09
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in lookaround-enumerable.gemspec
6
+ gemspec
@@ -0,0 +1,57 @@
1
+ # Lookaround Enumerable
2
+
3
+ When working with time series, it is common to perform operations that depend on a sliding window of values. Lookaround Enumerable adds two main methods, and several sub-helpers to assist with running map/collect, reduce/inject, and find_all/select queries that depend on the previous values (Enumerable#each_with_prev), or a whole window of values (Enumerable#each_with_window). This gem contains these methods as refinements.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'lookaround-enumerable'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install lookaround-enumerable
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'lookaround-enumerable'
25
+ using LookaroundEnum
26
+ ```
27
+
28
+ The `LookaroundEnum` contains the refinements, so they can be targeted to selected areas of code.
29
+
30
+ ```ruby
31
+ # Maps characters after a capital letter to "x"
32
+ "AbCdefgHiJKl".each_char.map_with_prev(1, filler: "a") {|x, previous| previous.upcase == previous ? "x" : x}.join
33
+ # => "AxCxefgHxJxx"
34
+
35
+ # select characters surrounded by > <, ignoring the bounds (crop)
36
+ "Ab>c<defg>h<i>j<kLm>n<op".each_char.select_with_window(-1..1, crop: true) { |left, item, right| left + right == "><" }.join
37
+ # => "cjhn"
38
+ ```
39
+
40
+ * Set what beyond the Enumerable is with `filler:`
41
+ * Ignore all iterations that look beyond the Enumerable with `crop: true`
42
+ * Remove extra details from chains with `trim: true`
43
+
44
+ See the documentation spec tests under `spec/` for more examples.
45
+
46
+
47
+ ### Wait, what are the proc's args?
48
+
49
+ That's a tricky question. By default, single left/right views _should_ just work, but you might have to play with the `expand` parameter or do a `p *args` to figure out more advanced usage, like chaining with memos or objects. The `each_with_prev` family does `|(*this), ((*previous1), ..., (*previous_n))|` with older/lower indexes to the right. The `each_with_window` family does `|((*previous_n), ..., (*previous1)), (*this), ((*next1), ..., (*next_n))|` with older/lower indexes on the left.
50
+
51
+ ## Development
52
+
53
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` or `rspec` to run the tests.
54
+
55
+ ## Contributing
56
+
57
+ Bug reports and pull requests are welcome on GitHub at https://github.com/byteit101/lookaround-enumerable.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,728 @@
1
+ =begin
2
+ Copyright 2020 Patrick Plenefisch <simonpatp@gmail.com>
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13
+ =end
14
+
15
+
16
+ ##
17
+ # Refinements for lookaround methods on Enumerable/Enumerator
18
+ #
19
+ # Use:
20
+ # using LookaroundEnum
21
+ #
22
+ # All methods are added to Enumerable
23
+ #
24
+ module LookaroundEnum
25
+
26
+ VERSION = "1.0.0"
27
+
28
+ # Refinements for Enumerable
29
+ refine Enumerable do
30
+
31
+ # See doc below, yard doesn't support refinements
32
+ def each_with_prev(size=1, crop: false, trim: false, filler: nil, expand: :single, &block)
33
+ raise ArgumentError, "previous size must not be negative" unless (0...2_000_000_000).include?(size)
34
+ raise ArgumentError, "Expand parameter isn't valid" unless [:none, :all, :single].include?(expand)
35
+ return to_enum(:__nbl_back_refinement_send, size, crop: crop, trim: trim, filler: filler, expand: expand) { __nbl_any_sized } unless block_given?
36
+
37
+ last = [filler] * size
38
+ skips = crop ? size : 0 # how many elements to skip
39
+
40
+ each do |*o| # call parent
41
+ issingle = o.length == 1
42
+ result = if skips != 0 # skip the first N if we don't want nil results
43
+ skips -= 1
44
+ nil
45
+ else
46
+ case expand
47
+ when :all then yield(*o, *last.dup)
48
+ when :none then yield(o, last.dup)
49
+ when :single
50
+ yield(LookaroundEnum.unwrap(o), LookaroundEnum.unwrap(last, size))
51
+ end
52
+ end
53
+ # maintain the last values
54
+ last.pop
55
+ last.unshift(trim ? o.first : LookaroundEnum.unwrap(o))
56
+
57
+ # return yield result
58
+ result
59
+ end
60
+ #self
61
+ end
62
+
63
+ def each_with_window(view=(-1..1), crop: false, trim: false, filler: nil, expand: :single, &blk)
64
+ center_index = -view.min
65
+ raise ArgumentError, "window view minimum must not be positive" unless (0...2_000_000_000).include?(center_index)
66
+ raise ArgumentError, "window view maximum must not be negative" unless (0...2_000_000_000).include?(view.max)
67
+ raise ArgumentError, "Expand parameter isn't valid" unless [:none, :all, :single].include?(expand)
68
+ width = view.size - 1 # width - 1 as the main arg counts as +1
69
+
70
+ # no lookahead, just defer to straight neighbor call
71
+ if view.max == 0
72
+ return each_with_prev(width, crop: crop, trim: trim, expand: expand, filler: filler, &blk) # TODO: test arity
73
+ end
74
+
75
+ return to_enum(:__nbl_window_refinement_send, view, crop: crop, trim: trim, filler: filler, expand: expand) { __nbl_any_sized } unless blk
76
+
77
+ last_row = [filler] * view.size
78
+ skips = view.max
79
+ last_result = nil
80
+
81
+ # helper for each invocation to skip the left sides. Note: we are always view.max items behind in order to "lookahead"
82
+ process = lambda do
83
+ last_result = if skips != 0
84
+ skips -= 1
85
+ nil
86
+ else
87
+ center = last_row[center_index]
88
+ right = last_row[(center_index+1)..-1]
89
+ left = last_row[0...center_index]
90
+ case expand
91
+ when :none then blk.call(left, center, right)
92
+ when :all then blk.call(*left, center, *right) # look into splatting the center
93
+ when :single then
94
+ if center_index == 0
95
+ blk.call(center, LookaroundEnum.unwrap(right))
96
+ else
97
+ maxsize = [left.size, right.size].max
98
+ blk.call(LookaroundEnum.unwrap(left, maxsize), center, LookaroundEnum.unwrap(right, maxsize))
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ # Process all the left hand sides
105
+ iresult = each_with_prev(width, crop: crop, trim: trim, filler: filler, expand: :none) do |arg, history|
106
+ rearg = arg.length == 1 ? arg : [arg] # keep multi-arguments together when reversing
107
+ last_row = (rearg + history).reverse # Could be done better
108
+ process.call
109
+ end
110
+
111
+ # and any remaining right hand sides
112
+ unless crop
113
+ view.max.times do |i|
114
+ last_row.shift
115
+ last_row << filler
116
+ process.call
117
+ end
118
+ end
119
+
120
+ return last_result
121
+ end
122
+
123
+
124
+ # map helpers and aliases
125
+ def map_with_prev(size=1, **kwargs, &block)
126
+ each_with_prev(size, **kwargs).map(&block)
127
+ end
128
+ alias_method :collect_with_prev, :map_with_prev
129
+ alias_method :pcollect, :map_with_prev
130
+ alias_method :pmap, :map_with_prev
131
+
132
+ # select helper and aliases
133
+ def select_with_prev(size=1, **kwargs, &block)
134
+ select.each_with_prev(size, **kwargs, &block)
135
+ end
136
+
137
+ alias_method :find_all_with_prev, :select_with_prev
138
+ alias_method :pfind_all, :select_with_prev
139
+ alias_method :pselect, :select_with_prev
140
+
141
+ # inject helper and aliases
142
+ def pinject(memo = NBL__PRIVATE_EMPTY, size=1, **kwargs, &block)
143
+ if memo.equal? NBL__PRIVATE_EMPTY
144
+ each_with_prev(size, **kwargs).reduce(&block)
145
+ else
146
+ each_with_prev(size, **kwargs).reduce(memo, &block) #T TODO: test
147
+ end
148
+ end
149
+ alias_method :reduce_with_prev, :pinject
150
+ alias_method :inject_with_prev, :pinject
151
+ alias_method :preduce, :pinject
152
+
153
+ # map helpers (windows) and aliases
154
+ def map_with_window(view=(-1..1), **kwargs, &block)
155
+ each_with_window(view, **kwargs).map(&block)
156
+ end
157
+ alias_method :collect_with_window, :map_with_window
158
+ alias_method :wcollect, :map_with_window
159
+ alias_method :wmap, :map_with_window
160
+
161
+ # select helpers (windows) and aliases
162
+ def select_with_window(view=(-1..1), **kwargs, &block)
163
+ map_with_window(view, **kwargs) do |*lcr|
164
+ a, b, c = *lcr
165
+ node = view.min == 0 ? a : b
166
+ [block.call(*lcr), node]
167
+ end.select{|(key, _)| key}.map{|_, value| value}
168
+ end
169
+
170
+ alias_method :find_all_with_window, :select_with_window
171
+ alias_method :wfind_all, :select_with_window
172
+ alias_method :wselect, :select_with_window
173
+
174
+ # inject helper and aliases
175
+ def winject(memo = NBL__PRIVATE_EMPTY, size=(-1..1), **kwargs, &block)
176
+ if memo.equal? NBL__PRIVATE_EMPTY
177
+ each_with_window(size, **kwargs).reduce(&block)
178
+ else
179
+ each_with_window(size, **kwargs).reduce(memo, &block)
180
+ end
181
+ end
182
+ alias_method :reduce_with_window, :winject
183
+ alias_method :inject_with_window, :winject
184
+ alias_method :wreduce, :winject
185
+
186
+
187
+ private
188
+ # :nodoc:
189
+ # Helper to get the size, or nil if unsupported
190
+ def __nbl_any_sized
191
+ respond_to?(:size) ? size : nil
192
+ end
193
+ end
194
+
195
+ private
196
+ # :nodoc:
197
+ # Helper to unwrap a single element array
198
+ def self.unwrap(array, size=array.length)
199
+ case size
200
+ when 1 then array.first
201
+ else array.dup
202
+ end
203
+ end
204
+
205
+ # :nodoc:
206
+ NBL__PRIVATE_EMPTY = {}
207
+ end
208
+
209
+ module Enumerable
210
+ using LookaroundEnum
211
+ # @api private
212
+ # @private
213
+ # @!visibility private
214
+ # Hack to support to_enum, which uses send, which doesn't work with refinements. This method is always monkey-patched in as a result
215
+ def __nbl_back_refinement_send(*args, **kwargs, &block)
216
+ each_with_prev(*args, **kwargs, &block)
217
+ end
218
+ # @api private
219
+ # @private
220
+ # @!visibility private
221
+ # Hack to support to_enum, which uses send, which doesn't work with refinements. This method is always monkey-patched in as a result
222
+ def __nbl_window_refinement_send(*args, **kwargs, &block)
223
+ each_with_window(*args, **kwargs, &block)
224
+ end
225
+
226
+ # Document via yard
227
+
228
+
229
+ ##
230
+ # @!method each_with_prev
231
+ #
232
+ # @overload each_with_prev(size=1, crop: false, trim: false, filler: nil, expand: :single)
233
+ # @return [Enumerable] The parent Enumerable
234
+ # @yield [(*args), (*previous)]
235
+ # @overload each_with_prev(size=1, crop: false, trim: false, filler: nil, expand: :single)
236
+ # @return [Enumerator] The external Enumerator
237
+ #
238
+ # Calls <em>block</em> with two (or more, depending on the <em>expand</em>) arguments: the item and
239
+ # the values at earlier indexes.
240
+ #
241
+ # If no block is given, an enumerator is returned instead.
242
+ #
243
+ # @param size [Integer] The number of previous elements to iterate with
244
+ # @example Size Examples
245
+ # (1..3).each_with_prev(1).to_a # => [[1, nil], [2, 1], [3, 2]]
246
+ # (1..3).each_with_prev(2).to_a # => [[1, [nil, nil]], [2, [1, nil]], [3, [2, 1]]]
247
+ #
248
+ # @param crop: [Bool] true if the iteration should only include values with no empty previous (skips first <em>size</em> number of elements), false if all elements iterated
249
+ # @example Crop Examples
250
+ # (1..3).each_with_prev(1, crop: false).to_a # => [[1, nil], [2, 1], [3, 2]]
251
+ # (1..3).each_with_prev(1, crop: true).to_a # => [[2, 1], [3, 2]]
252
+ #
253
+ #
254
+ # @param trim: [Bool] true if the previous elements should only be the first item from lower level iterators, false if all values should be saved. Note that setting this value is only useful on Enumerators or Enumerables that have more than one value.
255
+ # @example Trim Examples
256
+ # (1..3).each_with_object({}).each_with_prev(1, trim: false, expand: :all).to_a
257
+ # # => [[1, {}, nil], [2, {}, [1, {}]], [3, {}, [2, {}]]]
258
+ # (1..3).each_with_object({}).each_with_prev(1, trim: true, expand: :all).to_a
259
+ # # => [[1, {}, nil], [2, {}, 1], [3, {}, 2]]
260
+ #
261
+ # @param filler: [Any] the value to use for empty/no-value history cells at the start of the iteration. Does nothing when <em>crop</em> is true.
262
+ # @example Filler Examples
263
+ # (1..3).each_with_prev(1, filler: nil).to_a # => [[1, nil], [2, 1], [3, 2]]
264
+ # (1..3).each_with_prev(1, filler: 0).to_a # => [[1, 0], [2, 1], [3, 2]]
265
+ #
266
+ # @param expand: [Symbol] What argument style the block expects. See the valid options above (html doc) or below (source)
267
+ #
268
+ # <code>expand:</code>::
269
+ # (Symbol) Valid options are:
270
+ #
271
+ # <code>:none</code>:: Never expands, block always takes two arguments, each an array
272
+ #
273
+ # (1..3).each_with_prev(expand: :none) {|(current), (prev)| }
274
+ # (1..3).each_with_object({}).each_with_prev(2, expand: :none) {|(current, obj), (prev, prev2)| }
275
+ #
276
+ # <code>:single</code>:: (default) Expands if only one element, block always takes two arguments, each an array or an object
277
+ #
278
+ # (1..3).each_with_prev(expand: :single) {|current, prev| }
279
+ # (1..3).each_with_prev(2, expand: :single) {|current, (prev, prev2)| }
280
+ # (1..3).each_with_object({}).each_with_prev(2, expand: :single) {|(current, obj), (prev, prev2)| }
281
+ #
282
+ # <code>:all</code>:: Expands all sides, block takes two or more arguments, each an object
283
+ #
284
+ # (1..3).each_with_prev(expand: :all) {|current, prev| }
285
+ # (1..3).each_with_prev(2, expand: :all) {|current, prev, prev2| }
286
+ # (1..3).each_with_object({}).each_with_prev(2, expand: :all) {|current, obj, prev, prev2| }
287
+ #
288
+ #
289
+ #
290
+ # @raise [ArgumentError] If the arguments are invalid
291
+ #
292
+ #
293
+ #
294
+ #
295
+ #
296
+ #
297
+ #
298
+ #
299
+ #
300
+
301
+
302
+
303
+ ##
304
+ # @!method each_with_window
305
+ #
306
+ # @overload each_with_window(view=-1..1, crop: false, trim: false, filler: nil, expand: :single)
307
+ # @return [Enumerable] The parent Enumerable
308
+ # @yield [(*left), (*args), (*right)]
309
+ # @overload each_with_window(size=-1..1, crop: false, trim: false, filler: nil, expand: :single)
310
+ # @return [Enumerator] The external Enumerator
311
+ #
312
+ # Calls <em>block</em> with three (or more, depending on the <em>expand</em>) arguments: the item and
313
+ # the values at earlier and later indexes.
314
+ #
315
+ # If no block is given, an enumerator is returned instead.
316
+ #
317
+ # Important note: each_with_window is executed in a disjunct manner from the parent iterator. This can cause issues when chained with other Enumerators. Please use the built in helpers.
318
+ #
319
+ # @param view [Range] The number of items to look at to previous and upcoming indicies.
320
+ # @example View Examples
321
+ # ('a'..'d').each_with_window(-2..1).to_a # => [[[nil, nil], "a", ["b"]], [[nil, "a"], "b", ["c"]], [["a", "b"], "c", ["d"]], [["b", "c"], "d", [nil]]]
322
+ #
323
+ # @see each_with_prev For argument descriptions
324
+ #
325
+ # @raise [ArgumentError] If the arguments are invalid
326
+ #
327
+ #
328
+ #
329
+ #
330
+ #
331
+ #
332
+ #
333
+ #
334
+ #
335
+
336
+ # @!group Aliases
337
+
338
+ ##
339
+ # @!method map_with_prev
340
+ # @overload map_with_prev(*args)
341
+ # @return [Object] The result of the map
342
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
343
+ # @overload map_with_prev(*args)
344
+ # @return [Enumerator] The external Enumerator
345
+ #
346
+ # Aliases for each_with_prev(*args).map
347
+ #
348
+ # @see each_with_prev
349
+ # @see collect_with_prev
350
+ # @see pmap
351
+ # @see pcollect
352
+
353
+
354
+ ##
355
+ # @!method collect_with_prev
356
+ # @overload collect_with_prev(*args)
357
+ # @return [Object] The result of the map
358
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
359
+ # @overload collect_with_prev(*args)
360
+ # @return [Enumerator] The external Enumerator
361
+ #
362
+ # Aliases for each_with_prev(*args).map
363
+ #
364
+ # @see each_with_prev
365
+ # @see map_with_prev
366
+ # @see pmap
367
+ # @see pcollect
368
+
369
+
370
+ ##
371
+ # @!method pmap
372
+ # @overload pmap(*args)
373
+ # @return [Object] The result of the map
374
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
375
+ # @overload pmap(*args)
376
+ # @return [Enumerator] The external Enumerator
377
+ #
378
+ # Aliases for each_with_prev(*args).map
379
+ #
380
+ # @see each_with_prev
381
+ # @see map_with_prev
382
+ # @see collect_with_prev
383
+ # @see pcollect
384
+
385
+
386
+ ##
387
+ # @!method pcollect
388
+ # @overload pcollect(*args)
389
+ # @return [Object] The result of the map
390
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
391
+ # @overload pcollect(*args)
392
+ # @return [Enumerator] The external Enumerator
393
+ #
394
+ # Aliases for each_with_prev(*args).map
395
+ #
396
+ # @see each_with_prev
397
+ # @see map_with_prev
398
+ # @see collect_with_prev
399
+ # @see pmap
400
+
401
+
402
+
403
+
404
+ ##
405
+ # @!method select_with_prev
406
+ # @overload select_with_prev(*args)
407
+ # @return [Object] The result of the map
408
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
409
+ # @overload select_with_prev(*args)
410
+ # @return [Enumerator] The external Enumerator
411
+ #
412
+ # Aliases for select.each_with_prev(*args)
413
+ #
414
+ # @see each_with_prev
415
+ # @see find_all_with_prev
416
+ # @see pselect
417
+ # @see pfind_all
418
+
419
+
420
+ ##
421
+ # @!method find_all_with_prev
422
+ # @overload find_all_with_prev(*args)
423
+ # @return [Object] The result of the map
424
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
425
+ # @overload find_all_with_prev(*args)
426
+ # @return [Enumerator] The external Enumerator
427
+ #
428
+ # Aliases for select.each_with_prev(*args)
429
+ #
430
+ # @see each_with_prev
431
+ # @see select_with_prev
432
+ # @see pselect
433
+ # @see pfind_all
434
+
435
+
436
+ ##
437
+ # @!method pselect
438
+ # @overload pselect(*args)
439
+ # @return [Object] The result of the map
440
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
441
+ # @overload pselect(*args)
442
+ # @return [Enumerator] The external Enumerator
443
+ #
444
+ # Aliases for select.each_with_prev(*args)
445
+ #
446
+ # @see each_with_prev
447
+ # @see select_with_prev
448
+ # @see find_all_with_prev
449
+ # @see pfind_all
450
+
451
+
452
+ ##
453
+ # @!method pfind_all
454
+ # @overload pfind_all(*args)
455
+ # @return [Object] The result of the map
456
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
457
+ # @overload pfind_all(*args)
458
+ # @return [Enumerator] The external Enumerator
459
+ #
460
+ # Aliases for select.each_with_prev(*args)
461
+ #
462
+ # @see each_with_prev
463
+ # @see select_with_prev
464
+ # @see find_all_with_prev
465
+ # @see pselect
466
+
467
+
468
+
469
+ ##
470
+ # @!method inject_with_prev
471
+ # @overload inject_with_prev(memo=first, *args)
472
+ # @return [Object] The result of the map
473
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
474
+ # @overload inject_with_prev(memo=first, *args)
475
+ # @return [Enumerator] The external Enumerator
476
+ #
477
+ # Aliases for inject(memo).each_with_prev(*args)
478
+ #
479
+ # @see each_with_prev
480
+ # @see reduce_with_prev
481
+ # @see pinject
482
+ # @see preduce
483
+
484
+
485
+ ##
486
+ # @!method reduce_with_prev
487
+ # @overload reduce_with_prev(memo=first, *args)
488
+ # @return [Object] The result of the map
489
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
490
+ # @overload reduce_with_prev(memo=first, *args)
491
+ # @return [Enumerator] The external Enumerator
492
+ #
493
+ # Aliases for inject(memo).each_with_prev(*args)
494
+ #
495
+ # @see each_with_prev
496
+ # @see inject_with_prev
497
+ # @see pinject
498
+ # @see preduce
499
+
500
+
501
+ ##
502
+ # @!method pinject
503
+ # @overload pinject(memo=first, *args)
504
+ # @return [Object] The result of the map
505
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
506
+ # @overload pinject(memo=first, *args)
507
+ # @return [Enumerator] The external Enumerator
508
+ #
509
+ # Aliases for inject(memo).each_with_prev(*args)
510
+ #
511
+ # @see each_with_prev
512
+ # @see inject_with_prev
513
+ # @see reduce_with_prev
514
+ # @see preduce
515
+
516
+
517
+ ##
518
+ # @!method preduce
519
+ # @overload preduce(memo=first, *args)
520
+ # @return [Object] The result of the map
521
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_prev
522
+ # @overload preduce(memo=first, *args)
523
+ # @return [Enumerator] The external Enumerator
524
+ #
525
+ # Aliases for inject(memo).each_with_prev(*args)
526
+ #
527
+ # @see each_with_prev
528
+ # @see inject_with_prev
529
+ # @see reduce_with_prev
530
+ # @see pinject
531
+
532
+
533
+
534
+ ##
535
+ # @!method map_with_window
536
+ # @overload map_with_window(*args)
537
+ # @return [Object] The result of the map
538
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
539
+ # @overload map_with_window(*args)
540
+ # @return [Enumerator] The external Enumerator
541
+ #
542
+ # Aliases for each_with_window(*args).map
543
+ #
544
+ # @see each_with_window
545
+ # @see collect_with_window
546
+ # @see wmap
547
+ # @see wcollect
548
+
549
+
550
+ ##
551
+ # @!method collect_with_window
552
+ # @overload collect_with_window(*args)
553
+ # @return [Object] The result of the map
554
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
555
+ # @overload collect_with_window(*args)
556
+ # @return [Enumerator] The external Enumerator
557
+ #
558
+ # Aliases for each_with_window(*args).map
559
+ #
560
+ # @see each_with_window
561
+ # @see map_with_window
562
+ # @see wmap
563
+ # @see wcollect
564
+
565
+
566
+ ##
567
+ # @!method wmap
568
+ # @overload wmap(*args)
569
+ # @return [Object] The result of the map
570
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
571
+ # @overload wmap(*args)
572
+ # @return [Enumerator] The external Enumerator
573
+ #
574
+ # Aliases for each_with_window(*args).map
575
+ #
576
+ # @see each_with_window
577
+ # @see map_with_window
578
+ # @see collect_with_window
579
+ # @see wcollect
580
+
581
+
582
+ ##
583
+ # @!method wcollect
584
+ # @overload wcollect(*args)
585
+ # @return [Object] The result of the map
586
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
587
+ # @overload wcollect(*args)
588
+ # @return [Enumerator] The external Enumerator
589
+ #
590
+ # Aliases for each_with_window(*args).map
591
+ #
592
+ # @see each_with_window
593
+ # @see map_with_window
594
+ # @see collect_with_window
595
+ # @see wmap
596
+
597
+
598
+
599
+
600
+ ##
601
+ # @!method select_with_window
602
+ # @overload select_with_window(*args)
603
+ # @return [Object] The result of the map
604
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
605
+ # @overload select_with_window(*args)
606
+ # @return [Enumerator] The external Enumerator
607
+ #
608
+ # Aliases for select.each_with_window(*args)
609
+ #
610
+ # @see each_with_window
611
+ # @see find_all_with_window
612
+ # @see wselect
613
+ # @see wfind_all
614
+
615
+
616
+ ##
617
+ # @!method find_all_with_window
618
+ # @overload find_all_with_window(*args)
619
+ # @return [Object] The result of the map
620
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
621
+ # @overload find_all_with_window(*args)
622
+ # @return [Enumerator] The external Enumerator
623
+ #
624
+ # Aliases for select.each_with_window(*args)
625
+ #
626
+ # @see each_with_window
627
+ # @see select_with_window
628
+ # @see wselect
629
+ # @see wfind_all
630
+
631
+
632
+ ##
633
+ # @!method wselect
634
+ # @overload wselect(*args)
635
+ # @return [Object] The result of the map
636
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
637
+ # @overload wselect(*args)
638
+ # @return [Enumerator] The external Enumerator
639
+ #
640
+ # Aliases for select.each_with_window(*args)
641
+ #
642
+ # @see each_with_window
643
+ # @see select_with_window
644
+ # @see find_all_with_window
645
+ # @see wfind_all
646
+
647
+
648
+ ##
649
+ # @!method wfind_all
650
+ # @overload wfind_all(*args)
651
+ # @return [Object] The result of the map
652
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
653
+ # @overload wfind_all(*args)
654
+ # @return [Enumerator] The external Enumerator
655
+ #
656
+ # Aliases for select.each_with_window(*args)
657
+ #
658
+ # @see each_with_window
659
+ # @see select_with_window
660
+ # @see find_all_with_window
661
+ # @see wselect
662
+
663
+
664
+
665
+ ##
666
+ # @!method inject_with_window
667
+ # @overload inject_with_window(memo=first, *args)
668
+ # @return [Object] The result of the map
669
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
670
+ # @overload inject_with_window(memo=first, *args)
671
+ # @return [Enumerator] The external Enumerator
672
+ #
673
+ # Aliases for inject(memo).each_with_window(*args)
674
+ #
675
+ # @see each_with_window
676
+ # @see reduce_with_window
677
+ # @see winject
678
+ # @see wreduce
679
+
680
+
681
+ ##
682
+ # @!method reduce_with_window
683
+ # @overload reduce_with_window(memo=first, *args)
684
+ # @return [Object] The result of the map
685
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
686
+ # @overload reduce_with_window(memo=first, *args)
687
+ # @return [Enumerator] The external Enumerator
688
+ #
689
+ # Aliases for inject(memo).each_with_window(*args)
690
+ #
691
+ # @see each_with_window
692
+ # @see inject_with_window
693
+ # @see winject
694
+ # @see wreduce
695
+
696
+
697
+ ##
698
+ # @!method winject
699
+ # @overload winject(memo=first, *args)
700
+ # @return [Object] The result of the map
701
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
702
+ # @overload winject(memo=first, *args)
703
+ # @return [Enumerator] The external Enumerator
704
+ #
705
+ # Aliases for inject(memo).each_with_window(*args)
706
+ #
707
+ # @see each_with_window
708
+ # @see inject_with_window
709
+ # @see reduce_with_window
710
+ # @see wreduce
711
+
712
+
713
+ ##
714
+ # @!method wreduce
715
+ # @overload wreduce(memo=first, *args)
716
+ # @return [Object] The result of the map
717
+ # @yield [(*args), (*previous)] See the `expand` parameter of each_with_window
718
+ # @overload wreduce(memo=first, *args)
719
+ # @return [Enumerator] The external Enumerator
720
+ #
721
+ # Aliases for inject(memo).each_with_window(*args)
722
+ #
723
+ # @see each_with_window
724
+ # @see inject_with_window
725
+ # @see reduce_with_window
726
+ # @see winject
727
+
728
+ end
@@ -0,0 +1,35 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "lookaround-enumerable"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "lookaround-enumerable"
8
+ spec.version = LookaroundEnum::VERSION
9
+ spec.authors = ["Patrick Plenefisch"]
10
+ spec.email = ["simonpatp@gmail.com"]
11
+
12
+ spec.summary = %q{Look around at neighbor elements in Enumerable methods}
13
+ spec.description = %q{Lookaround Enumerable allows acccessing previous and upcoming elements in Enumerable methods, so that computations can depend on a window of values. Particularly useful for dragged state, time series, and other semi-stateful computations.}
14
+ spec.homepage = "https://github.com/byteit101/lookaround-enumerable"
15
+ spec.license = "BSD-3-Clause"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = spec.homepage
22
+ else
23
+ raise "RubyGems 2.0 or newer is required to protect against " \
24
+ "public gem pushes."
25
+ end
26
+
27
+ # Specify which files should be added to the gem when it is released.
28
+ spec.files = [".rspec", "Gemfile", "README.md", "Rakefile", "lib/lookaround-enumerable.rb", "lookaround-enumerable.gemspec"]
29
+
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.13"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "rspec", "~> 3.0"
35
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lookaround-enumerable
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Patrick Plenefisch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-10-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Lookaround Enumerable allows acccessing previous and upcoming elements
56
+ in Enumerable methods, so that computations can depend on a window of values. Particularly
57
+ useful for dragged state, time series, and other semi-stateful computations.
58
+ email:
59
+ - simonpatp@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".rspec"
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - lib/lookaround-enumerable.rb
69
+ - lookaround-enumerable.gemspec
70
+ homepage: https://github.com/byteit101/lookaround-enumerable
71
+ licenses:
72
+ - BSD-3-Clause
73
+ metadata:
74
+ homepage_uri: https://github.com/byteit101/lookaround-enumerable
75
+ source_code_uri: https://github.com/byteit101/lookaround-enumerable
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.0.3
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Look around at neighbor elements in Enumerable methods
95
+ test_files: []