-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsegment.go
77 lines (57 loc) · 2.42 KB
/
segment.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
package simpleflow
// SegmentFunc is a function that determines how an item of type `T` is segmented into a segment of type `S`
type SegmentFunc[T any, S comparable] func(T) S
type SegmentFuncKV[K comparable, V any, S comparable] func(K, V) S
// SegmentSlice takes a slice and breaks it into smaller segmented slices using the provided function `f`
// The segments are returned in a map where the segment is the key.
func SegmentSlice[T any, S comparable](items []T, f SegmentFunc[T, S]) map[S][]T {
segments := make(map[S][]T)
for ii := 0; ii < len(items); ii++ {
IncrementalSegmentSlice(segments, items[ii], f)
}
return segments
}
// IncrementalSegmentSlice adds the item to the correct segment inside `segments by calling `f` on `item`
func IncrementalSegmentSlice[T any, S comparable](segments map[S][]T, item T, f SegmentFunc[T, S]) {
s := f(item)
// Check if a segment has already been created, if not, create one
if _, ok := segments[s]; !ok {
segments[s] = []T{}
}
// Add the item to the segment
segments[s] = append(segments[s], item)
}
// SegmentMap takes a map and breaks it into smaller segmented maps using the provided function `f`
// The segments are returned in a map where the segment is the key.
func SegmentMap[K comparable, V any, S comparable](items map[K]V, f SegmentFuncKV[K, V, S]) map[S]map[K]V {
segments := make(map[S]map[K]V)
for k, v := range items {
IncrementalSegmentMap(segments, k, v, f)
}
return segments
}
// IncrementalSegmentMap adds the (key,value) pair to the correct segment inside `segments by calling `f` on `(k, v)`
func IncrementalSegmentMap[K comparable, V any, S comparable](segments map[S]map[K]V, k K, v V, f SegmentFuncKV[K, V, S]) {
s := f(k, v)
// Check if a segment has already been created, if not, create one
if _, ok := segments[s]; !ok {
segments[s] = map[K]V{}
}
// Add the item to the segment
segments[s][k] = v
}
// SegmentChan takes a channel and breaks it into smaller segmented slices using the provided function `f`
// The segments are returned in a map where the segment is the key.
func SegmentChan[T any, S comparable](items <-chan T, f SegmentFunc[T, S]) map[S][]T {
segments := make(map[S][]T)
for item := range items {
s := f(item)
// Check if a segment has already been created, if not, create one
if _, ok := segments[s]; !ok {
segments[s] = []T{}
}
// Add the item to the segment
segments[s] = append(segments[s], item)
}
return segments
}