-
Notifications
You must be signed in to change notification settings - Fork 0
/
collect.go
105 lines (94 loc) · 2.52 KB
/
collect.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
package streams
func Collect[T any](stream Stream[T]) []T {
var v T
var result []T
for stream.Next(&v) {
result = append(result, v)
}
return result
}
func (s Stream[T]) Collect() []T {
return Collect(s)
}
func CollectFirst[T any](stream Stream[T], count int) (first []T, rest Stream[T]) {
if count < 0 {
panic("CollectFirst: count < 0")
}
var v T
for len(first) < count && stream.Next(&v) {
first = append(first, v)
}
return first, stream
}
func (s Stream[T]) CollectFirst(count int) (first []T, rest Stream[T]) {
return CollectFirst(s, count)
}
func CollectLast[T any](stream Stream[T], count, maxSkip int) (skipped int, last []T, hasRest bool) {
processed := 0
if count < 0 {
panic("CollectLast: count < 0")
}
if count == 0 {
var v T
return 0, nil, stream.Next(&v)
}
var buffer []T
lastIdx := 0
var v T
for (maxSkip < 0 || processed < maxSkip+count) && stream.Next(&v) {
processed += 1
if len(buffer) < count {
buffer = append(buffer, v)
} else {
buffer[lastIdx] = v
lastIdx = (lastIdx + 1) % count
}
}
return processed - len(buffer), append(buffer[lastIdx:], buffer[:lastIdx]...), stream.Next(&v)
}
func (s Stream[T]) CollectLast(count, maxSkip int) (skip int, last []T, hasRest bool) {
return CollectLast(s, count, maxSkip)
}
func CollectFirstLast[T any](stream Stream[T], firstCount, lastCount, maxSkip int) (
first []T, skipped int, last []T, hasRest bool,
) {
if firstCount < 0 {
panic("CollectFirstLast: firstCount < 0")
}
if lastCount < 0 {
panic("CollectFirstLast: lastCount < 0")
}
first, stream = CollectFirst(stream, firstCount)
if len(first) < firstCount {
if len(first) < lastCount {
lastCount = len(first)
}
if lastCount == 0 {
var v T
return nil, 0, nil, stream.Next(&v)
}
last = make([]T, lastCount)
copy(last, first[len(first)-lastCount:])
return first, -lastCount, last, false
}
skipped, last, hasRest = CollectLast(stream, lastCount, maxSkip)
if len(last) < lastCount {
if len(last)+len(first) < lastCount {
lastCount = len(last) + len(first)
}
if lastCount == 0 {
return nil, skipped, nil, hasRest
}
copyFirst := lastCount - len(last)
mergedLast := make([]T, lastCount)
copy(mergedLast, first[len(first)-copyFirst:])
copy(mergedLast[copyFirst:], last)
return first, -copyFirst, mergedLast, hasRest
}
return first, skipped, last, hasRest
}
func (s Stream[T]) CollectFirstLast(firstCount, lastCount, maxSkip int) (
first []T, skipped int, last []T, hasRest bool,
) {
return CollectFirstLast(s, firstCount, lastCount, maxSkip)
}