-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflatmap.go
More file actions
82 lines (76 loc) · 1.68 KB
/
flatmap.go
File metadata and controls
82 lines (76 loc) · 1.68 KB
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
package iterator
// FlatMap returns a modifier to map items to iterators and flattens them into a single iterator
func FlatMap[T any, S any](fn func(int, int, T) (Iterator[S], error)) Modifier[T, S] {
return func(iter Iterator[T]) Iterator[S] {
var finished bool
var count int
var countOuter int
var curr Iterator[S]
var currItem S
var err error
return &iterator[S]{
next: func() bool {
if finished || err != nil {
return false
}
for curr == nil || !curr.Next() {
if curr != nil {
if err = curr.Err(); err != nil {
return false
}
if err = curr.Close(); err != nil {
return false
}
}
if !iter.Next() {
finished = true
return false
}
var item T
item, err = iter.Get()
if err != nil {
return false
}
curr, err = fn(countOuter, count, item)
if err != nil {
return false
}
count++
}
if currItem, err = curr.Get(); err != nil {
return false
}
countOuter++
return true
},
get: func() (S, error) {
return currItem, err
},
close: func() error {
if err := curr.Close(); err != nil {
iter.Close()
return err
}
return iter.Close()
},
err: func() error {
if err != nil {
return err
}
if curr != nil {
if err := curr.Err(); err != nil {
return err
}
}
return iter.Err()
},
}
}
}
// Flatten is a modifier that applies on iterator of iterators
// It flattens them into a single iterator
func Flatten[T any](iter Iterator[Iterator[T]]) Iterator[T] {
return FlatMap(func(_ int, _ int, iter Iterator[T]) (Iterator[T], error) {
return iter, nil
})(iter)
}