-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathconsumer.go
184 lines (172 loc) · 3.97 KB
/
consumer.go
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package goterator
func (iter *Iterator) iter(f PredicateFunc) {
skipWhileIsOver := false
ElementLoop:
for {
ok := iter.generator.Next()
if !ok {
return
}
element := iter.generator.Value()
for _, m := range iter.mappers {
switch mapper := m.(type) {
case mapFunc:
element = mapper(element)
case filterFunc:
if !mapper(element) {
continue ElementLoop
}
case takeValue:
if *mapper == 0 {
return
}
*mapper--
case takeWhileFunc:
if !mapper(element) {
return
}
case skipValue:
if *mapper > 0 {
*mapper--
continue ElementLoop
}
case skipWhileFunc:
if !skipWhileIsOver && mapper(element) {
continue ElementLoop
}
skipWhileIsOver = true
}
}
if !f(element) {
return
}
}
}
// ForEach consumes elements and runs `f` for each element.
// The iteration is broken if `f` returns false.
func (iter *Iterator) ForEach(f IterFunc) {
iter.iter(func(element interface{}) bool {
f(element)
return true
})
}
// Collect consumes elements and returns a slice of converted elements.
func (iter *Iterator) Collect() []interface{} {
var elements []interface{}
iter.iter(func(element interface{}) bool {
elements = append(elements, element)
return true
})
return elements
}
// Reduce consumes elements and runs `f` for each element.
// Returns the final state after iteration over all elements.
func (iter *Iterator) Reduce(initialState interface{}, f ReduceFunc) interface{} {
iter.iter(func(element interface{}) bool {
initialState = f(initialState, element)
return true
})
return initialState
}
// Find consumes elements and returns the first element that satisfies `f` (returning `true`).
// Returns `nil, false` if no element is found.
func (iter *Iterator) Find(f PredicateFunc) (interface{}, bool) {
var elem interface{}
ok := false
iter.iter(func(element interface{}) bool {
if f(element) {
elem = element
ok = true
return false
}
return true
})
return elem, ok
}
// Min consumes elements and returns the minimum element.
func (iter *Iterator) Min(f LessFunc) interface{} {
first := true
var min interface{}
iter.iter(func(element interface{}) bool {
if first || f(element, min) {
min = element
first = false
}
return true
})
return min
}
// Max consumes elements and returns the maximum element.
func (iter *Iterator) Max(f LessFunc) interface{} {
first := true
var max interface{}
iter.iter(func(element interface{}) bool {
if first || f(max, element) {
max = element
first = false
}
return true
})
return max
}
// All consumes elements and returns true if `f` returns true for all elements.
// Returns `true` for empty iterators.
func (iter *Iterator) All(f PredicateFunc) bool {
all := true
iter.iter(func(element interface{}) bool {
if !f(element) {
all = false
return false
}
return true
})
return all
}
// Any consumes elements and returns true if `f` returns true for at least one element.
// Returns `false` for empty iterators.
func (iter *Iterator) Any(f PredicateFunc) bool {
any := false
iter.iter(func(element interface{}) bool {
if f(element) {
any = true
return false
}
return true
})
return any
}
// Last consumes elements and returns the last element.
func (iter *Iterator) Last() interface{} {
var last interface{}
iter.iter(func(element interface{}) bool {
last = element
return true
})
return last
}
// Nth consumes elements and returns the `n`th element. Indexing starts from `0`.
// Returns an nil, false` if the length of iterator is less than `n`.
func (iter *Iterator) Nth(n int) (interface{}, bool) {
var nth interface{}
ok := false
index := 0
iter.iter(func(element interface{}) bool {
if index == n {
nth = element
ok = true
return false
}
index++
return true
})
return nth, ok
}
// Count consumes elements and returns the length of elements.
func (iter *Iterator) Count() int {
count := 0
iter.iter(func(element interface{}) bool {
count++
return true
})
return count
}