-
Notifications
You must be signed in to change notification settings - Fork 0
/
collections.go
108 lines (96 loc) · 2.71 KB
/
collections.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
package lib
import (
"fmt"
"sort"
)
// ContainsDuplicates returns true if the slice contains duplicates, false if not.
func ContainsDuplicates[V comparable](values []V) bool {
seenValues := make(map[V]bool)
for _, val := range values {
if _, exists := seenValues[val]; exists {
return true
}
seenValues[val] = true
}
return false
}
// GetSortedKeys returns the keys of the map in sorted order.
func GetSortedKeys[R interface {
~[]K
sort.Interface
}, K comparable, V any](m map[K]V) []K {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Sort(R(keys))
return keys
}
// UniqueSliceToSet converts a slice of unique values to a set.
// The function will panic if there are duplicate values.
func UniqueSliceToSet[K comparable](values []K) map[K]struct{} {
set := make(map[K]struct{}, len(values))
for _, sliceVal := range values {
if _, exists := set[sliceVal]; exists {
panic(
fmt.Sprintf(
"UniqueSliceToSet: duplicate value: %+v",
sliceVal,
),
)
}
set[sliceVal] = struct{}{}
}
return set
}
// UniqueSliceToMap converts a slice to a map using the provided keyFunc to generate the key.
func UniqueSliceToMap[K comparable, V any](slice []V, keyFunc func(V) K) map[K]V {
m := make(map[K]V)
for _, v := range slice {
k := keyFunc(v)
if _, exists := m[k]; exists {
panic(
fmt.Sprintf(
"UniqueSliceToMap: duplicate value: %+v",
v,
),
)
}
m[k] = v
}
return m
}
// MapSlice takes a function and executes that function on each element of a slice, returning the result.
// Note the function must return one result for each element of the slice.
func MapSlice[V any, E any](values []V, mapFunc func(V) E) []E {
mappedValues := make([]E, 0, len(values))
for _, value := range values {
mappedValues = append(mappedValues, mapFunc(value))
}
return mappedValues
}
// FilterSlice takes a function that returns a boolean on whether to include the element in the final
// result, and returns a slice of elements where the function returned true when called with each element.
func FilterSlice[V any](values []V, filterFunc func(V) bool) []V {
filteredValues := make([]V, 0, len(values))
for _, value := range values {
if filterFunc(value) {
filteredValues = append(filteredValues, value)
}
}
return filteredValues
}
// MergeAllMapsMustHaveDistinctKeys merges all the maps into a single map.
// Panics if there are duplicate keys.
func MergeAllMapsMustHaveDistinctKeys[K comparable, V any](maps ...map[K]V) map[K]V {
combinedMap := make(map[K]V)
for _, m := range maps {
for k, v := range m {
if _, exists := combinedMap[k]; exists {
panic(fmt.Sprintf("duplicate key: %v", k))
}
combinedMap[k] = v
}
}
return combinedMap
}