-
Notifications
You must be signed in to change notification settings - Fork 0
/
reverse.go
61 lines (54 loc) · 1.11 KB
/
reverse.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
package gcf
type reverseIterable[T any] struct {
itb Iterable[T]
}
type reverseIterator[T any] struct {
it Iterator[T]
built bool
iteratorItem[T]
}
// Reverse makes Iterable with reverse order elements.
//
// itb := gcf.FromSlice([]int{1, 2, 3})
// itb = gcf.Reverse(itb)
func Reverse[T any](itb Iterable[T]) Iterable[T] {
if isEmpty(itb) {
return orEmpty(itb)
}
// reverse in reverse is original Iterable.
if itbr, ok := itb.(*reverseIterable[T]); ok {
return itbr.itb
}
return &reverseIterable[T]{itb}
}
func (itb *reverseIterable[T]) Iterator() Iterator[T] {
return &reverseIterator[T]{
it: itb.itb.Iterator(),
}
}
func (it *reverseIterator[T]) MoveNext() bool {
if it.done {
return false
}
if !it.built {
it.build()
}
if !it.it.MoveNext() {
it.MarkDone()
return false
}
it.current = it.it.Current()
return true
}
func (it *reverseIterator[T]) Current() T {
return it.current
}
func (it *reverseIterator[T]) build() {
s := iteratorToSlice(it.it)
slen := len(s)
for i := 0; i < slen/2; i++ {
s[i], s[slen-i-1] = s[slen-i-1], s[i]
}
it.it = makeSliceIterator(s)
it.built = true
}