...
1
16
17 package sets
18
19 import (
20 "cmp"
21 "sort"
22 )
23
24
25 type Set[T comparable] map[T]Empty
26
27
28 func cast[T comparable](s map[T]Empty) Set[T] { return s }
29
30
31
32 func New[T comparable](items ...T) Set[T] {
33 ss := make(Set[T], len(items))
34 ss.Insert(items...)
35 return ss
36 }
37
38
39
40 func KeySet[T comparable, V any](theMap map[T]V) Set[T] {
41 ret := make(Set[T], len(theMap))
42 for keyValue := range theMap {
43 ret.Insert(keyValue)
44 }
45 return ret
46 }
47
48
49 func (s Set[T]) Insert(items ...T) Set[T] {
50 for _, item := range items {
51 s[item] = Empty{}
52 }
53 return s
54 }
55
56 func Insert[T comparable](set Set[T], items ...T) Set[T] {
57 return set.Insert(items...)
58 }
59
60
61 func (s Set[T]) Delete(items ...T) Set[T] {
62 for _, item := range items {
63 delete(s, item)
64 }
65 return s
66 }
67
68
69
70
71
72
73
74
75 func (s Set[T]) Clear() Set[T] {
76 for key := range s {
77 delete(s, key)
78 }
79 return s
80 }
81
82
83 func (s Set[T]) Has(item T) bool {
84 _, contained := s[item]
85 return contained
86 }
87
88
89 func (s Set[T]) HasAll(items ...T) bool {
90 for _, item := range items {
91 if !s.Has(item) {
92 return false
93 }
94 }
95 return true
96 }
97
98
99 func (s Set[T]) HasAny(items ...T) bool {
100 for _, item := range items {
101 if s.Has(item) {
102 return true
103 }
104 }
105 return false
106 }
107
108
109 func (s Set[T]) Clone() Set[T] {
110 result := make(Set[T], len(s))
111 for key := range s {
112 result.Insert(key)
113 }
114 return result
115 }
116
117
118
119
120
121
122
123 func (s1 Set[T]) Difference(s2 Set[T]) Set[T] {
124 result := New[T]()
125 for key := range s1 {
126 if !s2.Has(key) {
127 result.Insert(key)
128 }
129 }
130 return result
131 }
132
133
134
135
136
137
138
139 func (s1 Set[T]) SymmetricDifference(s2 Set[T]) Set[T] {
140 return s1.Difference(s2).Union(s2.Difference(s1))
141 }
142
143
144
145
146
147
148
149 func (s1 Set[T]) Union(s2 Set[T]) Set[T] {
150 result := s1.Clone()
151 for key := range s2 {
152 result.Insert(key)
153 }
154 return result
155 }
156
157
158
159
160
161
162 func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] {
163 var walk, other Set[T]
164 result := New[T]()
165 if s1.Len() < s2.Len() {
166 walk = s1
167 other = s2
168 } else {
169 walk = s2
170 other = s1
171 }
172 for key := range walk {
173 if other.Has(key) {
174 result.Insert(key)
175 }
176 }
177 return result
178 }
179
180
181 func (s1 Set[T]) IsSuperset(s2 Set[T]) bool {
182 for item := range s2 {
183 if !s1.Has(item) {
184 return false
185 }
186 }
187 return true
188 }
189
190
191
192
193 func (s1 Set[T]) Equal(s2 Set[T]) bool {
194 return len(s1) == len(s2) && s1.IsSuperset(s2)
195 }
196
197 type sortableSliceOfGeneric[T cmp.Ordered] []T
198
199 func (g sortableSliceOfGeneric[T]) Len() int { return len(g) }
200 func (g sortableSliceOfGeneric[T]) Less(i, j int) bool { return less[T](g[i], g[j]) }
201 func (g sortableSliceOfGeneric[T]) Swap(i, j int) { g[i], g[j] = g[j], g[i] }
202
203
204
205
206
207 func List[T cmp.Ordered](s Set[T]) []T {
208 res := make(sortableSliceOfGeneric[T], 0, len(s))
209 for key := range s {
210 res = append(res, key)
211 }
212 sort.Sort(res)
213 return res
214 }
215
216
217 func (s Set[T]) UnsortedList() []T {
218 res := make([]T, 0, len(s))
219 for key := range s {
220 res = append(res, key)
221 }
222 return res
223 }
224
225
226 func (s Set[T]) PopAny() (T, bool) {
227 for key := range s {
228 s.Delete(key)
229 return key, true
230 }
231 var zeroValue T
232 return zeroValue, false
233 }
234
235
236 func (s Set[T]) Len() int {
237 return len(s)
238 }
239
240 func less[T cmp.Ordered](lhs, rhs T) bool {
241 return lhs < rhs
242 }
243
View as plain text