-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaggregation.go
68 lines (61 loc) · 1.78 KB
/
aggregation.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
package goiter
import "iter"
// Count counts the number of elements yielded by the input iterator.
func Count[TIter SeqX[T], T any](iterator TIter) int {
count := 0
for _ = range iterator {
count++
}
return count
}
// Count2 counts the number of elements yielded by the input iterator.
func Count2[TIter Seq2X[T1, T2], T1 any, T2 any](iterator TIter) int {
count := 0
for _, _ = range iterator {
count++
}
return count
}
// Reduce is basically Reduce function in functional programming.
// The following example uses Reduce to sum up the numbers from 1 to 10:
//
// sum := goiter.Reduce(goiter.Range(1, 10), 0, func(acc, v int) int {
// return acc + v
// })
func Reduce[TIter SeqX[T], TAcc any, T any](
iterator TIter,
init TAcc,
folder func(TAcc, T) TAcc,
) TAcc {
var result = init
for v := range iterator {
result = folder(result, v)
}
return result
}
// Scan is similar to Reduce function, but it returns an iterator that will yield the reduced value of each round.
// So, the following code will create an iterator that yields 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, where each value is the sum of numbers from 1 to the current number.
// iterator := goiter.Scan(goiter.Range(1, 10), 0, func(acc, v int) int {
// return acc + v
// })
func Scan[TIter SeqX[T], TAcc any, T any](
iterator TIter,
init TAcc,
folder func(TAcc, T) TAcc,
) Iterator[TAcc] {
return func(yield func(TAcc) bool) {
next, stop := iter.Pull(iter.Seq[T](iterator))
defer stop()
acc := init
for {
v, ok := next()
if !ok {
return
}
acc = folder(acc, v)
if !yield(acc) {
return
}
}
}
}