generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 7
/
slices.go
117 lines (105 loc) · 2.34 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
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
package slices
import (
"cmp"
"sort"
)
func Map[T, U any](slice []T, fn func(T) U) []U {
result := make([]U, len(slice))
for i, v := range slice {
result[i] = fn(v)
}
return result
}
func MapErr[T, U any](slice []T, fn func(T) (U, error)) ([]U, error) {
result := make([]U, len(slice))
for i, v := range slice {
var err error
result[i], err = fn(v)
if err != nil {
return nil, err
}
}
return result, nil
}
func Filter[T any](slice []T, fn func(T) bool) []T {
result := make([]T, 0, len(slice))
for _, v := range slice {
if fn(v) {
result = append(result, v)
}
}
return result
}
// GroupBy groups the elements of a slice by the result of a function.
func GroupBy[T any, K comparable](slice []T, fn func(T) K) map[K][]T {
result := make(map[K][]T)
for _, v := range slice {
key := fn(v)
result[key] = append(result[key], v)
}
return result
}
func Reduce[T, U any](slice []T, initial U, fn func(U, T) U) U {
result := initial
for _, v := range slice {
result = fn(result, v)
}
return result
}
// AppendOrReplace appends a value to a slice if the slice does not contain a
// value for which the given function returns true. If the slice does contain
// such a value, it is replaced.
func AppendOrReplace[T any](slice []T, value T, fn func(T) bool) []T {
for i, v := range slice {
if fn(v) {
slice[i] = value
return slice
}
}
return append(slice, value)
}
// Sort returns a sorted clone of slice.
func Sort[T cmp.Ordered](slice []T) []T {
out := make([]T, len(slice))
copy(out, slice)
sort.Slice(out, func(i, j int) bool {
return out[i] < out[j]
})
return out
}
func FlatMap[T, U any](slice []T, fn func(T) []U) []U {
result := make([]U, 0, len(slice))
for _, v := range slice {
result = append(result, fn(v)...)
}
return result
}
func Find[T any](slice []T, fn func(T) bool) (T, bool) {
for _, v := range slice {
if fn(v) {
return v, true
}
}
var zero T
return zero, false
}
func FindVariant[T any, U any](slice []U) (T, bool) {
for _, el := range slice {
if found, ok := any(el).(T); ok {
return found, true
}
}
var zero T
return zero, false
}
func Unique[T comparable](slice []T) []T {
seen := make(map[T]struct{})
result := make([]T, 0, len(slice))
for _, v := range slice {
if _, ok := seen[v]; !ok {
seen[v] = struct{}{}
result = append(result, v)
}
}
return result
}