-
Notifications
You must be signed in to change notification settings - Fork 0
/
slices.go
59 lines (54 loc) · 1.71 KB
/
slices.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
package pp
import (
"slices"
)
// DivideSliceInSize receives a slice `s` and divide it into groups with `n` elements each,
// then it uses a step factory to generate steps for each group.
// `n` must be greater than 0 or it will panic.
func DivideSliceInSize[T any](s []T, n int, stepFactory func(T) Step) (steps Steps) {
for chunk := range slices.Chunk(s, n) {
batch := make(Steps, 0, len(chunk))
for _, v := range chunk {
batch = append(batch, stepFactory(v))
}
steps = append(steps, batch.Group())
}
return steps
}
// divideSliceInGroups receive a slice `s` and breaks it into `n` sub-slices.
func divideSliceInGroups[T any](s []T, n int) [][]T {
length := float64(len(s))
if length == 0 {
return nil
}
var out [][]T
for segment := 0; segment < n; segment++ {
startIndex := int(float64(segment) / float64(n) * length)
endIndex := int(float64(segment+1) / float64(n) * length)
if startIndex == endIndex {
continue
}
out = append(out, s[startIndex:endIndex])
}
return out
}
// DivideSliceInGroups receives a slice `s` and divide it into `n` groups,
// then it uses a step factory to generate steps for each group.
func DivideSliceInGroups[T any](s []T, n int, stepFactory func(T) Step) (steps Steps) {
for _, chunk := range divideSliceInGroups(s, n) {
batch := make(Steps, 0, len(chunk))
for _, v := range chunk {
batch = append(batch, stepFactory(v))
}
steps = append(steps, batch.Group())
}
return steps
}
// ForEach takes a slice `s` and a stepFactory, and creates a step for each element inside.
func ForEach[T any](s []T, stepFactory func(T, int) Step) Step {
batch := make(Steps, 0, len(s))
for i := range s {
batch = append(batch, stepFactory(s[i], i))
}
return batch.Group()
}