-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathset.go
62 lines (53 loc) · 1.33 KB
/
set.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
package set
import "sort"
type ordered interface {
~int | ~string
}
// Set is a set of values of type V, indexed by keys of type K. We require an orderable type, so that we can
// provide a deterministic output. There are other ways to return a deterministic output (i.e., maintain the insert order),
// but this is the simplest.
type Set[K ordered, V any] struct {
valuesByKey map[K]V
getKey func(V) K
}
func NewSet[T ordered](vals ...T) *Set[T, T] {
return NewSetWithCustomKey(func(v T) T {
return v
}, vals...)
}
func NewSetWithCustomKey[K ordered, V any](getKey func(V) K, vals ...V) *Set[K, V] {
set := &Set[K, V]{
valuesByKey: make(map[K]V),
getKey: getKey,
}
set.Add(vals...)
return set
}
func (s *Set[K, V]) Add(vals ...V) {
for _, val := range vals {
s.valuesByKey[s.getKey(val)] = val
}
}
func (s *Set[K, V]) Has(val V) bool {
_, ok := s.valuesByKey[s.getKey(val)]
return ok
}
func (s *Set[K, V]) Values() []V {
values := make([]V, 0, len(s.valuesByKey))
for _, val := range s.valuesByKey {
values = append(values, val)
}
sort.Slice(values, func(i, j int) bool {
return s.getKey(values[i]) < s.getKey(values[j])
})
return values
}
func Difference[K ordered, V any](a, b *Set[K, V]) []V {
var vals []V
for _, val := range a.Values() {
if !b.Has(val) {
vals = append(vals, val)
}
}
return vals
}