...
1
2 package set
3
4 import (
5 "maps"
6 "slices"
7 )
8
9 type Set[K comparable] map[K]void
10 type void struct{}
11
12 var member = void{}
13
14 func New[K comparable]() Set[K] {
15 return Set[K]{}
16 }
17
18
19 func FromSlice[S ~[]K, K comparable](slice S) Set[K] {
20 set := New[K]()
21 set.Add(slice...)
22 return set
23 }
24
25
26 func FromMap[M ~map[K]V, K comparable, V any](m M) Set[K] {
27 return FromSlice(mapKeys(m))
28 }
29
30
31 func (set Set[K]) ToSlice() []K {
32 return mapKeys(set)
33 }
34
35
36 func (set Set[K]) Add(items ...K) {
37 for _, item := range items {
38 set[item] = member
39 }
40 }
41
42
43 func (set Set[K]) Remove(items ...K) {
44 for _, item := range items {
45 delete(set, item)
46 }
47 }
48
49
50 func (set Set[K]) HasMember(item K) bool {
51 _, ok := set[item]
52 return ok
53 }
54
55
56 func (left Set[K]) Union(right Set[K]) Set[K] {
57 union := Set[K]{}
58
59 for item := range left {
60 union.Add(item)
61 }
62
63 for item := range right {
64 union.Add(item)
65 }
66
67 return union
68 }
69
70
71 func (left Set[K]) Intersection(right Set[K]) Set[K] {
72 intersection := Set[K]{}
73
74 for item := range left {
75 if right.HasMember(item) {
76 intersection.Add(item)
77 }
78 }
79
80 return intersection
81 }
82
83
84 func (left Set[K]) Difference(right Set[K]) Set[K] {
85 difference := left
86
87 for item := range right {
88 difference.Remove(item)
89 }
90
91 return difference
92 }
93
94
95 func (left Set[K]) SymmetricDifference(right Set[K]) Set[K] {
96 return left.Union(right).Difference(left.Intersection(right))
97 }
98
99 func mapKeys[M ~map[K]V, K comparable, V any](m M) []K {
100 return slices.Collect(maps.Keys(m))
101 }
102
View as plain text