-
Notifications
You must be signed in to change notification settings - Fork 0
/
skip.go
120 lines (108 loc) · 2.29 KB
/
skip.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
package gcf
type skipIterable[T any] struct {
itb Iterable[T]
count int
}
type skipIterator[T any] struct {
it Iterator[T]
count int
i int
iteratorItem[T]
}
// Skip makes Iterable with elements excepting counted elements from ahead.
//
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.Skip(itb, 2)
//
// If count is 0, returns original Iterable.
// If count is negative, raises panic.
func Skip[T any](itb Iterable[T], count int) Iterable[T] {
if count < 0 {
panic("count for Skip must not be negative.")
}
if isEmpty(itb) {
return orEmpty(itb)
}
if count == 0 {
return itb
}
return &skipIterable[T]{itb, count}
}
func (itb *skipIterable[T]) Iterator() Iterator[T] {
return &skipIterator[T]{
it: itb.itb.Iterator(),
count: itb.count,
}
}
func (it *skipIterator[T]) MoveNext() bool {
if it.done {
return false
}
for it.i < it.count && it.it.MoveNext() {
it.i++
}
if !it.it.MoveNext() {
it.MarkDone()
return false
}
it.current = it.it.Current()
return true
}
func (it *skipIterator[T]) Current() T {
return it.current
}
type skipWhileIterable[T any] struct {
itb Iterable[T]
whileFunc func(v T) bool
}
type skipWhileIterator[T any] struct {
it Iterator[T]
whileFunc func(v T) bool
skipDone bool
iteratorItem[T]
}
// SkipWhile makes Iterable with elements excepting elements that whileFunc is true from ahead.
//
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.SkipWhile(itb, func(v int) bool { return v <= 2 })
//
// If whileFunc is nil, returns original Iterable.
func SkipWhile[T any](itb Iterable[T], whileFunc func(v T) bool) Iterable[T] {
if isEmpty(itb) {
return orEmpty(itb)
}
if whileFunc == nil {
return itb
}
return &skipWhileIterable[T]{itb, whileFunc}
}
func (itb *skipWhileIterable[T]) Iterator() Iterator[T] {
return &skipWhileIterator[T]{
it: itb.itb.Iterator(),
whileFunc: itb.whileFunc,
}
}
func (it *skipWhileIterator[T]) MoveNext() bool {
if it.done {
return false
}
if !it.skipDone {
for it.it.MoveNext() {
if it.whileFunc(it.it.Current()) {
continue
}
it.skipDone = true
it.current = it.it.Current()
return true
}
}
if !it.it.MoveNext() {
it.MarkDone()
return false
}
it.current = it.it.Current()
return true
}
func (it *skipWhileIterator[T]) Current() T {
return it.current
}