totally_lazy 0.0.20 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/compiler.xml +22 -0
- data/.idea/encodings.xml +6 -0
- data/.idea/misc.xml +19 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.travis.yml +2 -5
- data/Gemfile +6 -8
- data/Guardfile +2 -17
- data/LICENSE +202 -0
- data/Rakefile +18 -33
- data/VERSION +1 -1
- data/contributors.txt +1 -0
- data/lib/comparators.rb +9 -0
- data/lib/enumerators.rb +74 -0
- data/lib/functions.rb +66 -0
- data/lib/numbers.rb +38 -0
- data/lib/option.rb +38 -268
- data/lib/pair.rb +13 -51
- data/lib/predicates.rb +5 -0
- data/lib/sequence.rb +171 -526
- data/lib/strings.rb +13 -0
- data/lib/totally_lazy.rb +14 -165
- data/readme.md +2 -0
- data/spec/option_spec.rb +6 -182
- data/spec/sequence_spec.rb +202 -132
- data/spec/spec_helper.rb +0 -13
- data/totally_lazy.iml +74 -0
- metadata +58 -71
- data/.document +0 -5
- data/.rspec +0 -1
- data/LICENSE.txt +0 -20
- data/README.md +0 -173
- data/lib/any.rb +0 -13
- data/lib/functor.rb +0 -92
- data/lib/generators.rb +0 -161
- data/lib/parallel/parallel.rb +0 -442
- data/lib/parallel/processor_count.rb +0 -85
- data/lib/predicates/compare.rb +0 -25
- data/lib/predicates/conversions.rb +0 -22
- data/lib/predicates/numbers.rb +0 -21
- data/lib/predicates/predicates.rb +0 -141
- data/lib/predicates/where.rb +0 -34
- data/lib/predicates/where_processor.rb +0 -13
- data/lib/type_check.rb +0 -19
- data/lib/utils.rb +0 -9
- data/spec/functor_spec.rb +0 -35
- data/spec/generators_spec.rb +0 -37
- data/spec/pair_spec.rb +0 -44
- data/spec/predicate_spec.rb +0 -77
- data/spec/serialization_spec.rb +0 -56
- data/spec/type_check_spec.rb +0 -20
- data/spec/util_spec.rb +0 -10
- data/totally_lazy.gemspec +0 -101
data/lib/sequence.rb
CHANGED
@@ -1,642 +1,287 @@
|
|
1
1
|
class NoSuchElementException < RuntimeError
|
2
2
|
end
|
3
3
|
|
4
|
-
class UnsupportedTypeException < RuntimeError
|
5
|
-
end
|
6
|
-
|
7
|
-
class UnsupportedMethodException < RuntimeError
|
8
|
-
end
|
9
|
-
|
10
|
-
# Array pimps
|
11
|
-
class Array
|
12
|
-
def to_seq
|
13
|
-
sequence(self).flatten
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
4
|
module Sequences
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# == Parameters:
|
22
|
-
# items::
|
23
|
-
# Varargs - any valid ruby objects can be supplied
|
24
|
-
#
|
25
|
-
# == Returns:
|
26
|
-
# A sequence
|
27
|
-
#
|
28
|
-
# == Examples
|
29
|
-
#
|
30
|
-
# sequence(1,2,3,4).filter(even) # lazily returns 2,4
|
31
|
-
# sequence(1,2).map(as_string) # lazily returns "1","2"
|
32
|
-
# sequence(1, 2).map_concurrently(to_string) # lazily distributes the work to background threads
|
33
|
-
# sequence(1,2,3).take(2) # lazily returns 1,2
|
34
|
-
# sequence(1,2,3).drop(2) # lazily returns 3
|
35
|
-
# sequence(1,2,3).tail # lazily returns 2,3
|
36
|
-
# sequence(1,2,3).head # eagerly returns 1
|
37
|
-
# sequence(1,2,3).head_option # eagerly returns an option
|
38
|
-
# some(sequence(1,2,3)).get_or_else(empty) # eagerly returns value or else empty sequence
|
39
|
-
# sequence(1, 2, 3, 4, 5).filter(where(is greater_than 2).and(is odd)) # lazily returns 3,5
|
40
|
-
# def sequence(*items)
|
41
|
-
# if items.size == 1
|
42
|
-
# if [Range, Hash, Array, Set].include?(items.first.class)
|
43
|
-
# Sequence.new(items.first)
|
44
|
-
# elsif items.first.nil?
|
45
|
-
# empty
|
46
|
-
# else
|
47
|
-
# Sequence.new(items)
|
48
|
-
# end
|
49
|
-
# else
|
50
|
-
# Sequence.new(items)
|
51
|
-
# end
|
52
|
-
# end
|
5
|
+
def empty
|
6
|
+
EMPTY
|
7
|
+
end
|
53
8
|
|
54
9
|
def sequence(*items)
|
55
10
|
if items.first.nil?
|
56
11
|
empty
|
57
12
|
else
|
58
|
-
Sequence.new(items)
|
13
|
+
Sequence.new(items.lazy)
|
59
14
|
end
|
60
15
|
end
|
61
16
|
|
62
|
-
def
|
63
|
-
|
64
|
-
if entry.respond_to?(:flatten)
|
65
|
-
entry.flatten
|
66
|
-
else
|
67
|
-
raise UnsupportedMethodException.new, "flatten is not supported by: #{self.entries.class}"
|
68
|
-
end
|
69
|
-
end.flatten)
|
17
|
+
def zip(left, right)
|
18
|
+
left.zip(right)
|
70
19
|
end
|
71
20
|
|
72
|
-
|
73
|
-
|
74
|
-
# == Returns:
|
75
|
-
# An empty sequence
|
76
|
-
#
|
77
|
-
# == Examples
|
78
|
-
#
|
79
|
-
# empty
|
80
|
-
# some(sequence(1,2,3)).get_or_else(empty) # eagerly returns value or else empty sequence
|
81
|
-
def empty
|
82
|
-
Empty.new
|
21
|
+
def take(sequence, count)
|
22
|
+
Sequence.new(sequence.enumerator.take(count))
|
83
23
|
end
|
84
24
|
|
85
|
-
def
|
86
|
-
sequence(
|
25
|
+
def drop(sequence, count)
|
26
|
+
Sequence.new(sequence.enumerator.drop(count))
|
87
27
|
end
|
88
28
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
def initialize(obj, &block)
|
94
|
-
super() { |yielder|
|
95
|
-
begin
|
96
|
-
obj.each { |x|
|
97
|
-
if block
|
98
|
-
block.call(yielder, x)
|
99
|
-
else
|
100
|
-
yielder << x
|
101
|
-
end
|
102
|
-
}
|
103
|
-
rescue StopIteration
|
104
|
-
end
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
def <=>(object)
|
109
|
-
self.entries <=> object.entries
|
110
|
-
end
|
111
|
-
|
112
|
-
def flat_map(predicate=nil, &block)
|
113
|
-
if predicate
|
114
|
-
Sequence.new(self) { |yielder, val|
|
115
|
-
val.each {|x|
|
116
|
-
v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(x).apply(predicate.predicates) : predicate.exec.call(x)
|
117
|
-
yielder << v unless v.nil?
|
118
|
-
}
|
119
|
-
}
|
120
|
-
else
|
121
|
-
Sequence.new(self) { |yielder, val|
|
122
|
-
val.each {|e|
|
123
|
-
yielder << block.call(e)
|
124
|
-
}
|
125
|
-
}
|
126
|
-
end
|
127
|
-
end
|
128
|
-
alias collect_concat flat_map
|
129
|
-
|
130
|
-
def map(predicate=nil, &block)
|
131
|
-
if predicate
|
132
|
-
Sequence.new(self) { |yielder, val|
|
133
|
-
v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.exec.call(val)
|
134
|
-
yielder << v unless v.nil?
|
135
|
-
}
|
136
|
-
else
|
137
|
-
Sequence.new(self) { |yielder, val|
|
138
|
-
yielder << block.call(val)
|
139
|
-
}
|
140
|
-
end
|
141
|
-
end
|
29
|
+
def repeat(item)
|
30
|
+
Sequence.new(repeat_enumerator(item))
|
31
|
+
end
|
142
32
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
# case operation_or_value
|
147
|
-
# when Symbol
|
148
|
-
# # convert things like reduce(:+) into reduce { |s,e| s + e }
|
149
|
-
# return reduce { |s,e| s.send(operation_or_value, e) }
|
150
|
-
# when nil
|
151
|
-
# acc = nil
|
152
|
-
# else
|
153
|
-
# acc = operation_or_value
|
154
|
-
# end
|
155
|
-
#
|
156
|
-
# each do |a|
|
157
|
-
# if acc.nil?
|
158
|
-
# acc = a
|
159
|
-
# else
|
160
|
-
# acc = yield(acc, a)
|
161
|
-
# end
|
162
|
-
# end
|
163
|
-
#
|
164
|
-
# return acc
|
165
|
-
# end
|
166
|
-
|
167
|
-
def select(predicate=nil, &block)
|
168
|
-
if predicate
|
169
|
-
Sequence.new(self) { |yielder, val|
|
170
|
-
v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.exec.call(val)
|
171
|
-
yielder << v unless v.nil?
|
172
|
-
}
|
173
|
-
else
|
174
|
-
Sequence.new(self) { |yielder, val|
|
175
|
-
if block.call(val)
|
176
|
-
yielder << val
|
177
|
-
end
|
178
|
-
}
|
179
|
-
end
|
180
|
-
end
|
33
|
+
def repeat_fn(item)
|
34
|
+
Sequence.new(repeat_fn_enumerator(item))
|
35
|
+
end
|
181
36
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
def reject(predicate=nil, &block)
|
186
|
-
if predicate
|
187
|
-
Sequence.new(self) { |yielder, val|
|
188
|
-
v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates, true) : predicate.exec.call(val, :self, true)
|
189
|
-
yielder << v unless v.nil?
|
190
|
-
}
|
191
|
-
else
|
192
|
-
Sequence.new(self) { |yielder, val|
|
193
|
-
unless block.call(val)
|
194
|
-
yielder << val
|
195
|
-
end
|
196
|
-
}
|
197
|
-
end
|
198
|
-
end
|
37
|
+
def sort(sequence, comparator=ascending)
|
38
|
+
Sequence.new(sequence.enumerator.sort { |a, b| comparator.(a, b) }.lazy)
|
39
|
+
end
|
199
40
|
|
200
|
-
|
41
|
+
def map_concurrently(sequence, fn=nil, &block)
|
42
|
+
call_concurrently(sequence.map(defer_return(block_given? ? ->(value) { block.call(value) } : fn)))
|
43
|
+
end
|
201
44
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
end
|
207
|
-
}
|
208
|
-
end
|
45
|
+
# noinspection RubyTooManyMethodsInspection
|
46
|
+
class Sequence
|
47
|
+
include Comparable
|
48
|
+
attr_reader :enumerator
|
209
49
|
|
210
|
-
def
|
211
|
-
Sequence.
|
212
|
-
|
213
|
-
unless i < n
|
214
|
-
g.yield v
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end)
|
218
|
-
end
|
219
|
-
|
220
|
-
def drop_while(&block)
|
221
|
-
dropping = true
|
222
|
-
Sequence.new(self) { |yielder, val|
|
223
|
-
if dropping
|
224
|
-
if not block.call(val)
|
225
|
-
yielder << val
|
226
|
-
dropping = false
|
227
|
-
end
|
228
|
-
else
|
229
|
-
yielder << val
|
230
|
-
end
|
231
|
-
}
|
50
|
+
def initialize(enumerator)
|
51
|
+
raise "Sequence only accepts Enumerator::Lazy, not #{enumerator.class}" unless (enumerator.class == Enumerator::Lazy)
|
52
|
+
@enumerator = enumerator
|
232
53
|
end
|
233
54
|
|
234
|
-
def
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
end
|
243
|
-
end)
|
244
|
-
end
|
245
|
-
|
246
|
-
def take_while(&block)
|
247
|
-
Sequence.new(self) { |yielder, val|
|
248
|
-
if block.call(val)
|
249
|
-
yielder << val
|
250
|
-
else
|
251
|
-
raise StopIteration
|
252
|
-
end
|
253
|
-
}
|
55
|
+
def is_empty?
|
56
|
+
@enumerator.rewind
|
57
|
+
begin
|
58
|
+
@enumerator.peek
|
59
|
+
false
|
60
|
+
rescue
|
61
|
+
true
|
62
|
+
end
|
254
63
|
end
|
255
64
|
|
256
|
-
def
|
257
|
-
|
258
|
-
Sequence.new(self) { |yielder, val|
|
259
|
-
ary = enums.map { |e| e.next }
|
260
|
-
if block
|
261
|
-
yielder << block.call(ary)
|
262
|
-
else
|
263
|
-
yielder << ary
|
264
|
-
end
|
265
|
-
}
|
65
|
+
def size
|
66
|
+
@enumerator.count
|
266
67
|
end
|
267
68
|
|
268
|
-
def
|
269
|
-
|
69
|
+
def head
|
70
|
+
@enumerator.first
|
270
71
|
end
|
271
72
|
|
272
|
-
alias
|
73
|
+
alias first head
|
273
74
|
|
274
|
-
def
|
275
|
-
|
276
|
-
sequence.peek_values.empty?
|
277
|
-
rescue StopIteration
|
278
|
-
true
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
def head
|
283
|
-
sequence.empty? ? raise(NoSuchElementException.new, 'The sequence was empty') : sequence.entries.first
|
75
|
+
def second
|
76
|
+
tail.head
|
284
77
|
end
|
285
78
|
|
286
79
|
def head_option
|
287
|
-
|
80
|
+
option(head)
|
288
81
|
end
|
289
82
|
|
290
83
|
def last
|
291
|
-
|
84
|
+
reverse.head
|
292
85
|
end
|
293
86
|
|
294
87
|
def last_option
|
295
|
-
|
88
|
+
reverse.head_option
|
296
89
|
end
|
297
90
|
|
298
|
-
def
|
299
|
-
|
91
|
+
def reverse
|
92
|
+
Sequence.new(Enumerators::reverse(@enumerator))
|
300
93
|
end
|
301
94
|
|
302
95
|
def tail
|
303
|
-
|
304
|
-
|
305
|
-
|
96
|
+
unless has_next(@enumerator)
|
97
|
+
raise NoSuchElementException.new
|
98
|
+
end
|
99
|
+
Sequence.new(@enumerator.drop(1))
|
306
100
|
end
|
307
101
|
|
308
102
|
def init
|
309
|
-
|
310
|
-
size = self.count
|
311
|
-
self.empty? ? raise(NoSuchElementException.new, 'The sequence was empty') : self.first(size-1).each { |i| g.yield i }
|
312
|
-
end)
|
103
|
+
reverse.tail.reverse
|
313
104
|
end
|
314
105
|
|
315
|
-
def
|
316
|
-
|
317
|
-
|
318
|
-
|
106
|
+
def map(fn=nil, &block)
|
107
|
+
assert_funcs(fn, block_given?)
|
108
|
+
Sequence.new(@enumerator.map { |value|
|
109
|
+
block_given? ? block.call(value) : fn.(value)
|
110
|
+
})
|
319
111
|
end
|
320
112
|
|
321
|
-
def
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
raise(Exception.new, 'The subject of transposition must be multidimensional') unless self.to_a.first.is_a?(Array)
|
327
|
-
end
|
328
|
-
result = []
|
329
|
-
max = option(self.to_a.max { |a, b| a.size <=> b.size })
|
330
|
-
max_size = max.get_or_throw(NoSuchElementException, 'The option was empty').size
|
331
|
-
max_size.times do |i|
|
332
|
-
result[i] = [self.to_a.first.size]
|
333
|
-
self.to_a.each_with_index { |r, j| result[i][j] = r[i] }
|
334
|
-
end
|
335
|
-
result
|
336
|
-
result.each { |i| g.yield i }
|
337
|
-
end)
|
338
|
-
end
|
339
|
-
|
340
|
-
def join(target_sequence)
|
341
|
-
Sequence.new(Sequence::Generator.new do |g|
|
342
|
-
raise(Exception.new, 'The target (right side) must be a sequence') unless target_sequence.kind_of?(Sequences::Sequence)
|
343
|
-
self.entries.push(target_sequence.entries).flatten.each { |i| g.yield i unless i.is_a?(Empty) }
|
344
|
-
end)
|
345
|
-
end
|
346
|
-
|
347
|
-
alias << join
|
348
|
-
|
349
|
-
def add(target_sequence)
|
350
|
-
Sequence.new(Sequence::Generator.new do |g|
|
351
|
-
(self.entries + target_sequence.entries).each { |i| g.yield i }
|
352
|
-
end)
|
353
|
-
end
|
354
|
-
|
355
|
-
alias + add
|
356
|
-
|
357
|
-
def append(item)
|
358
|
-
Sequence.new(Sequence::Generator.new do |g|
|
359
|
-
elements = self.entries
|
360
|
-
elements = elements.reject { |i| i.is_a?(Empty) }
|
361
|
-
(elements << item).each { |i| g.yield i }
|
362
|
-
end)
|
363
|
-
end
|
364
|
-
|
365
|
-
def to_seq
|
366
|
-
Sequence.new(Sequence::Generator.new do |g|
|
367
|
-
self.entries.map { |e| Type.responds(e, :entries); e.entries }.flatten.each { |i| g.yield i }
|
368
|
-
end)
|
369
|
-
end
|
370
|
-
|
371
|
-
def to_maps(symbolize=true)
|
372
|
-
Sequence.new(Sequence::Generator.new do |g|
|
373
|
-
self.each_slice(2) do |k, v|
|
374
|
-
if symbolize
|
375
|
-
g.yield k.to_s.to_sym => v
|
376
|
-
else
|
377
|
-
g.yield k => v
|
378
|
-
end
|
379
|
-
end
|
380
|
-
end)
|
381
|
-
end
|
382
|
-
|
383
|
-
def to_map(symbolize=true)
|
384
|
-
Maps.merge(to_maps(symbolize))
|
113
|
+
def fold(seed, fn=nil, &block)
|
114
|
+
assert_funcs(fn, block_given?)
|
115
|
+
@enumerator.inject(seed) { |accumulator, value|
|
116
|
+
block_given? ? block.call(accumulator, value) : fn.(accumulator, value)
|
117
|
+
}
|
385
118
|
end
|
386
119
|
|
387
|
-
|
388
|
-
Sequence.new(Sequence::Generator.new do |g|
|
389
|
-
self.entries.map { |e| Type.check(e, Pair::Pair); [e.key, e.value] }.flatten.each { |i| g.yield i }
|
390
|
-
end)
|
391
|
-
end
|
120
|
+
alias fold_left fold
|
392
121
|
|
393
|
-
def
|
394
|
-
|
395
|
-
|
396
|
-
|
122
|
+
def fold_right(seed, fn=nil, &block)
|
123
|
+
assert_funcs(fn, block_given?)
|
124
|
+
Enumerators::reverse(@enumerator).inject(seed) { |accumulator, value|
|
125
|
+
block_given? ? block.call(value, accumulator) : fn.(value, accumulator)
|
126
|
+
}
|
397
127
|
end
|
398
128
|
|
399
|
-
def
|
400
|
-
|
401
|
-
|
402
|
-
|
129
|
+
def reduce(fn=nil, &block)
|
130
|
+
assert_funcs(fn, block_given?)
|
131
|
+
@enumerator.inject { |accumulator, value|
|
132
|
+
block_given? ? block.call(accumulator, value) : fn.(accumulator, value)
|
133
|
+
}
|
403
134
|
end
|
404
135
|
|
405
|
-
|
406
|
-
Sequence.new(Sequence::Generator.new do |g|
|
407
|
-
self.each_slice(2) { |k, v| g.yield pair(k, v) }
|
408
|
-
end)
|
409
|
-
end
|
136
|
+
alias reduce_left reduce
|
410
137
|
|
411
|
-
def
|
412
|
-
|
413
|
-
|
414
|
-
|
138
|
+
def reduce_right(fn=nil, &block)
|
139
|
+
assert_funcs(fn, block_given?)
|
140
|
+
Enumerators::reverse(@enumerator).inject { |accumulator, value|
|
141
|
+
block_given? ? block.call(value, accumulator) : fn.(value, accumulator)
|
415
142
|
}
|
416
|
-
|
417
|
-
self.entries
|
418
|
-
else
|
143
|
+
end
|
419
144
|
|
420
|
-
|
421
|
-
|
145
|
+
def find(fn_pred=nil, &block_pred)
|
146
|
+
assert_funcs(fn_pred, block_given?)
|
147
|
+
@enumerator.rewind
|
148
|
+
while has_next(@enumerator)
|
149
|
+
item = @enumerator.next
|
150
|
+
result = block_given? ? block_pred.call(item) : fn_pred.(item)
|
151
|
+
if result
|
152
|
+
return(some(item))
|
153
|
+
end
|
422
154
|
end
|
155
|
+
none
|
423
156
|
end
|
424
157
|
|
425
|
-
def
|
426
|
-
Sequence.new(
|
427
|
-
if item.is_a?(Hash)
|
428
|
-
self.map do |e|
|
429
|
-
item.map { |k, v|
|
430
|
-
raise(UnsupportedMethodException.new, "Tried to call method: #{k} on #{e.class} but method not supported") unless e.respond_to?(k) or e.respond_to?(":#{k}=")
|
431
|
-
begin
|
432
|
-
e.send(k, v) if e.respond_to?(k); e
|
433
|
-
rescue
|
434
|
-
e.send("#{k}=", v) if e.respond_to?("#{k}="); e
|
435
|
-
end
|
436
|
-
}.first
|
437
|
-
end
|
438
|
-
else
|
439
|
-
self.map { item }
|
440
|
-
end.each { |i| g.yield i }
|
441
|
-
end)
|
158
|
+
def zip(other)
|
159
|
+
Sequence.new(pair_enumerator(@enumerator, other.enumerator))
|
442
160
|
end
|
443
161
|
|
444
|
-
def
|
445
|
-
|
162
|
+
def zip_with_index
|
163
|
+
Sequences.zip(range_from(0), self)
|
446
164
|
end
|
447
165
|
|
448
|
-
def
|
449
|
-
|
166
|
+
def find_index_of(fn_pred=nil, &block_pred)
|
167
|
+
assert_funcs(fn_pred, block_given?)
|
168
|
+
zip_with_index.find(->(pair) { block_given? ? block_pred.call(pair.second) : fn_pred.(pair.second) }).map(->(pair) { pair.first })
|
450
169
|
end
|
451
170
|
|
452
|
-
def
|
453
|
-
|
454
|
-
serializer(c, self.entries)
|
455
|
-
c
|
171
|
+
def take(count)
|
172
|
+
Sequences::take(self, count)
|
456
173
|
end
|
457
174
|
|
458
|
-
def
|
459
|
-
|
460
|
-
|
461
|
-
Sequence.new(c)
|
175
|
+
def take_while(fn_pred=nil, &block_pred)
|
176
|
+
assert_funcs(fn_pred, block_given?)
|
177
|
+
Sequence.new(@enumerator.take_while { |value| block_given? ? block_pred.call(value) : fn_pred.(value) })
|
462
178
|
end
|
463
179
|
|
464
|
-
def
|
465
|
-
|
180
|
+
def drop(count)
|
181
|
+
Sequences::drop(self, count)
|
466
182
|
end
|
467
183
|
|
468
|
-
def
|
469
|
-
|
470
|
-
|
471
|
-
self.sort_by { |e| block.call(e) }.each { |i| g.yield i }
|
472
|
-
end)
|
473
|
-
else
|
474
|
-
Sequence.new(Sequence::Generator.new do |g|
|
475
|
-
self.sort_by { |e| attr.map { |v| e.send(v) } }.each { |i| g.yield i }
|
476
|
-
end)
|
477
|
-
end
|
184
|
+
def drop_while(fn_pred=nil, &block_pred)
|
185
|
+
assert_funcs(fn_pred, block_given?)
|
186
|
+
Sequence.new(@enumerator.drop_while { |value| block_given? ? block_pred.call(value) : fn_pred.(value) })
|
478
187
|
end
|
479
188
|
|
480
|
-
def
|
481
|
-
|
482
|
-
|
483
|
-
end)
|
189
|
+
def flat_map(fn=nil, &block)
|
190
|
+
assert_funcs(fn, block_given?)
|
191
|
+
map(block_given? ? ->(value) { block.call(value) } : fn).flatten
|
484
192
|
end
|
485
193
|
|
486
|
-
def
|
487
|
-
|
194
|
+
def flatten
|
195
|
+
Sequence.new(flatten_enumerator(enumerator))
|
488
196
|
end
|
489
197
|
|
490
|
-
def
|
491
|
-
|
198
|
+
def sort_by(comparator)
|
199
|
+
Sequences::sort(self, comparator)
|
492
200
|
end
|
493
201
|
|
494
|
-
def
|
495
|
-
|
202
|
+
def contains?(value)
|
203
|
+
@enumerator.member?(value)
|
496
204
|
end
|
497
205
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
item.is_some? ? item.get.value : none
|
206
|
+
def exists?(fn_pred=nil, &block_pred)
|
207
|
+
assert_funcs(fn_pred, block_given?)
|
208
|
+
@enumerator.any? { |value| block_given? ? block_pred.call(value) : fn_pred.(value) }
|
502
209
|
end
|
503
210
|
|
504
|
-
def
|
505
|
-
|
506
|
-
|
211
|
+
def for_all?(fn_pred=nil, &block_pred)
|
212
|
+
assert_funcs(fn_pred, block_given?)
|
213
|
+
@enumerator.all? { |value| block_given? ? block_pred.call(value) : fn_pred.(value) }
|
507
214
|
end
|
508
215
|
|
509
|
-
def
|
510
|
-
|
511
|
-
|
512
|
-
end)
|
216
|
+
def filter(fn_pred=nil, &block_pred)
|
217
|
+
assert_funcs(fn_pred, block_given?)
|
218
|
+
Sequence.new(@enumerator.select { |value| block_given? ? block_pred.call(value) : fn_pred.(value) })
|
513
219
|
end
|
514
220
|
|
515
|
-
def
|
516
|
-
|
517
|
-
|
518
|
-
Parallel.map(self.entries, options) { |val|
|
519
|
-
predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.exec.call(val)
|
520
|
-
}.each { |i| g.yield i unless i.nil? }
|
521
|
-
end)
|
522
|
-
else
|
523
|
-
Sequence.new(Sequence::Generator.new do |g|
|
524
|
-
Parallel.map(self.entries, options) { |val| block.call(val) }.each { |i| g.yield i }
|
525
|
-
end)
|
526
|
-
end
|
221
|
+
def reject(fn_pred=nil, &block_pred)
|
222
|
+
assert_funcs(fn_pred, block_given?)
|
223
|
+
filter(Predicates::not(block_given? ? ->(value) { block_pred.call(value) } : fn_pred))
|
527
224
|
end
|
528
225
|
|
529
|
-
def
|
530
|
-
|
226
|
+
def group_by(fn=nil, &block)
|
227
|
+
assert_funcs(fn, block_given?)
|
228
|
+
groups = @enumerator.group_by { |value| block_given? ? block.call(value) : fn.(value) }
|
229
|
+
Sequence.new(groups.to_a.map { |group| Group.new(group[0], group[1].lazy) }.lazy)
|
531
230
|
end
|
532
231
|
|
533
|
-
def
|
534
|
-
|
535
|
-
|
536
|
-
end)
|
232
|
+
def each(fn=nil, &block)
|
233
|
+
assert_funcs(fn, block_given?)
|
234
|
+
@enumerator.each { |value| block_given? ? block.call(value) : fn.(value) }
|
537
235
|
end
|
538
236
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
Sequence.new(self)
|
237
|
+
def map_concurrently(fn=nil, &block)
|
238
|
+
assert_funcs(fn, block_given?)
|
239
|
+
Sequences::map_concurrently(self, block_given? ? ->(value) { block.call(value) } : fn)
|
543
240
|
end
|
544
241
|
|
545
|
-
def
|
546
|
-
|
242
|
+
def realise
|
243
|
+
Sequence.new(@enumerator.to_a.lazy)
|
547
244
|
end
|
548
245
|
|
549
|
-
def
|
550
|
-
entries
|
551
|
-
if entry.is_a?(Sequences::Sequence)
|
552
|
-
data = []
|
553
|
-
serializer(data, entry)
|
554
|
-
container << {type: :sequence, values: data}
|
555
|
-
elsif entry.is_a?(Pair::Pair)
|
556
|
-
if entry.second.is_a?(Sequences::Sequence)
|
557
|
-
data = []
|
558
|
-
serializer(data, entry)
|
559
|
-
container << {type: :pair, values: data}
|
560
|
-
else
|
561
|
-
container << {type: :pair, values: entry.to_map}
|
562
|
-
end
|
563
|
-
elsif entry.is_a?(Option::Some)
|
564
|
-
container << {type: :some, values: entry.value}
|
565
|
-
elsif entry.is_a?(Option::None)
|
566
|
-
container << {type: :none, values: nil}
|
567
|
-
elsif entry.respond_to?(:each)
|
568
|
-
data = []
|
569
|
-
serializer(data, entry)
|
570
|
-
container << {type: entry.class, values: data}
|
571
|
-
else
|
572
|
-
container << entry
|
573
|
-
end
|
574
|
-
end
|
246
|
+
def <=>(other)
|
247
|
+
@enumerator.entries <=> other.enumerator.entries
|
575
248
|
end
|
576
249
|
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
if entry.is_a?(Hash)
|
581
|
-
if entry[:type] == :sequence
|
582
|
-
data = []
|
583
|
-
deserializer(data, entry[:values])
|
584
|
-
container << Sequence.new(data)
|
585
|
-
elsif entry[:type] == :pair
|
586
|
-
if entry[:values].is_a?(Array)
|
587
|
-
container << pair(entry[:values].first, Sequence.new(entry[:values][1][:values]))
|
588
|
-
else
|
589
|
-
container << pair(entry[:values].keys.first, entry[:values].values.first)
|
590
|
-
end
|
591
|
-
elsif entry[:type] == :some
|
592
|
-
container << some(entry[:values])
|
593
|
-
elsif entry[:type] == :none
|
594
|
-
container << none
|
595
|
-
elsif entry[:type] == Hash
|
596
|
-
container << entry[:values].map{|e| {e[:values].first => e[:values].last } }.reduce({}) { |a, b| a.merge(b) }
|
597
|
-
else
|
598
|
-
container << entry[:type].send(:new, entry[:values])
|
599
|
-
end
|
600
|
-
else
|
601
|
-
container << entry
|
602
|
-
end
|
603
|
-
end
|
250
|
+
private
|
251
|
+
def assert_funcs(fn, block_given)
|
252
|
+
raise 'Cannot pass both lambda and block expressions' if !fn.nil? && block_given
|
604
253
|
end
|
605
|
-
|
606
254
|
end
|
607
255
|
|
608
|
-
|
609
|
-
|
610
|
-
def initialize(obj=[], &block)
|
611
|
-
super(obj) { |yielder|
|
612
|
-
begin
|
613
|
-
obj.each { |x|
|
614
|
-
if block
|
615
|
-
block.call(yielder, x)
|
616
|
-
else
|
617
|
-
yielder << x
|
618
|
-
end
|
619
|
-
}
|
620
|
-
rescue StopIteration
|
621
|
-
end
|
622
|
-
}
|
623
|
-
end
|
624
|
-
|
256
|
+
def group(key, enumerator)
|
257
|
+
Group.new(key, enumerator)
|
625
258
|
end
|
626
259
|
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
260
|
+
class Group < Sequence
|
261
|
+
include Comparable
|
262
|
+
attr_reader :key
|
638
263
|
|
264
|
+
def initialize(key, enumerator)
|
265
|
+
super(enumerator)
|
266
|
+
@key = key
|
267
|
+
end
|
639
268
|
|
269
|
+
def <=>(other)
|
270
|
+
(@key <=> other.key) <=> (enumerator.entries<=>(other.enumerator.entries))
|
271
|
+
end
|
272
|
+
end
|
640
273
|
|
274
|
+
private
|
641
275
|
|
276
|
+
EMPTY=Sequence.new([].lazy)
|
642
277
|
|
278
|
+
def pair_enumerator(left, right)
|
279
|
+
Enumerator.new do |y|
|
280
|
+
left.rewind
|
281
|
+
right.rewind
|
282
|
+
loop do
|
283
|
+
y << pair(left.next, right.next)
|
284
|
+
end
|
285
|
+
end.lazy
|
286
|
+
end
|
287
|
+
end
|