/
denumerable.rb
77 lines (65 loc) · 1.4 KB
/
denumerable.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
require 'facets/enumerator'
#require 'facets/enumerable/take'
# Classes which include Denumerable will get versions of map,
# select, and so on, which return a Denumerator, so that they
# work horizontally without creating intermediate arrays.
#
# @author Brian Candler
# @author Trans
module Denumerable
#
def map
Denumerator.new do |output|
each do |*input|
output.yield yield(*input)
end
end
end
alias :collect :map
#
def select
Denumerator.new do |output|
each do |*input|
output.yield(*input) if yield(*input)
end
end
end
alias :find_all :select
#
def reject
Denumerator.new do |output|
each do |*input|
output.yield(*input) unless yield(*input)
end
end
end
# Limit to the first n items in the list
def take(n)
Denumerator.new do |output|
count = 0
each do |*input|
break if count >= n
output.yield(*input)
count += 1
end
end
end
# Skip the first n items in the list
def skip(n)
Denumerator.new do |output|
count = 0
each do |*input|
output.yield(*input) if count >= n
count += 1
end
end
end
# TODO: add more methods, e.g. grep, take_while etc.
end
# = Denumerator
#
# A class like Enumerator, but which has 'lazy' versions of map, select etc.
#
class Denumerator < Enumerator
include Denumerable
end