github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/collection/mutable/set.go (about) 1 package mutable 2 3 import ( 4 "fmt" 5 6 breakLoop "github.com/m4gshm/gollections/break/loop" 7 "github.com/m4gshm/gollections/c" 8 "github.com/m4gshm/gollections/collection" 9 "github.com/m4gshm/gollections/collection/mutable/ordered" 10 "github.com/m4gshm/gollections/loop" 11 "github.com/m4gshm/gollections/map_" 12 "github.com/m4gshm/gollections/slice" 13 ) 14 15 // WrapSet creates a set using a map as the internal storage. 16 func WrapSet[T comparable](elements map[T]struct{}) *Set[T] { 17 return &Set[T]{elements: elements} 18 } 19 20 // Set is a collection implementation that provides element uniqueness. The elements must be comparable. 21 type Set[T comparable] struct { 22 elements map[T]struct{} 23 } 24 25 var ( 26 _ c.Addable[int] = (*Set[int])(nil) 27 _ c.AddableNew[int] = (*Set[int])(nil) 28 _ c.AddableAll[c.ForEach[int]] = (*Set[int])(nil) 29 _ c.AddableAllNew[c.ForEach[int]] = (*Set[int])(nil) 30 _ c.Deleteable[int] = (*Set[int])(nil) 31 _ c.DeleteableVerify[int] = (*Set[int])(nil) 32 _ collection.Set[int] = (*Set[int])(nil) 33 _ fmt.Stringer = (*Set[int])(nil) 34 ) 35 36 // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled. 37 func (s *Set[T]) All(consumer func(T) bool) { 38 for v := range s.elements { 39 if !consumer(v) { 40 return 41 } 42 } 43 } 44 45 // Loop creates a loop to iterate through the collection. 46 func (s *Set[T]) Loop() loop.Loop[T] { 47 h := s.Head() 48 return (&h).Next 49 } 50 51 // IterEdit creates iterator that can delete iterable elements 52 func (s *Set[T]) IterEdit() c.DelIterator[T] { 53 h := s.Head() 54 return &h 55 } 56 57 // Deprecated: Head is deprecated. Will be replaced by rance-over function iterator. 58 // Head creates an iterator to iterate through the collection. 59 func (s *Set[T]) Head() SetIter[T] { 60 var elements map[T]struct{} 61 if s != nil { 62 elements = s.elements 63 } 64 return NewSetIter(elements, s.DeleteOne) 65 } 66 67 // Deprecated: First is deprecated. Will be replaced by rance-over function iterator. 68 // First returns the first element of the collection, an iterator to iterate over the remaining elements, and true\false marker of availability next elements. 69 // If no more elements then ok==false. 70 func (s *Set[T]) First() (SetIter[T], T, bool) { 71 var ( 72 iterator = s.Head() 73 first, ok = iterator.Next() 74 ) 75 return iterator, first, ok 76 } 77 78 // Slice collects the elements to a slice 79 func (s *Set[T]) Slice() (out []T) { 80 if s != nil { 81 if elements := s.elements; elements != nil { 82 out = map_.Keys(elements) 83 } 84 } 85 return out 86 } 87 88 // Append collects the values to the specified 'out' slice 89 func (s *Set[T]) Append(out []T) []T { 90 if s != nil { 91 if elements := s.elements; elements != nil { 92 out = map_.AppendKeys(s.elements, out) 93 } 94 } 95 return out 96 } 97 98 // Clone returns copy of the collection 99 func (s *Set[T]) Clone() *Set[T] { 100 var elements map[T]struct{} 101 if s != nil { 102 elements = map_.Clone(s.elements) 103 } 104 return WrapSet(elements) 105 } 106 107 // IsEmpty returns true if the collection is empty 108 func (s *Set[T]) IsEmpty() bool { 109 return s.Len() == 0 110 } 111 112 // Len returns amount of the elements 113 func (s *Set[T]) Len() int { 114 if s == nil { 115 return 0 116 } 117 return len(s.elements) 118 } 119 120 // Contains checks if the collection contains an element 121 func (s *Set[T]) Contains(element T) (ok bool) { 122 if s != nil { 123 _, ok = s.elements[element] 124 } 125 return ok 126 } 127 128 // Add adds elements in the collection 129 func (s *Set[T]) Add(elements ...T) { 130 if s != nil { 131 for _, element := range elements { 132 s.AddOne(element) 133 } 134 } 135 } 136 137 // AddOne adds an element in the collection 138 func (s *Set[T]) AddOne(element T) { 139 if s == nil { 140 return 141 } else if elements := s.elements; elements == nil { 142 s.elements = map[T]struct{}{element: {}} 143 } else { 144 elements[element] = struct{}{} 145 } 146 } 147 148 // AddNew inserts elements if they are not contained in the collection 149 func (s *Set[T]) AddNew(elements ...T) bool { 150 if s == nil { 151 return false 152 } 153 ok := false 154 for _, element := range elements { 155 ok = s.AddOneNew(element) || ok 156 } 157 return ok 158 } 159 160 // AddOneNew inserts an element if it is not contained in the collection 161 func (s *Set[T]) AddOneNew(element T) (ok bool) { 162 if s != nil { 163 elements := s.elements 164 if elements == nil { 165 elements = map[T]struct{}{} 166 s.elements = elements 167 } 168 if ok = !s.Contains(element); ok { 169 elements[element] = struct{}{} 170 } 171 } 172 return ok 173 } 174 175 // AddAll inserts all elements from the "other" collection 176 func (s *Set[T]) AddAll(elements c.ForEach[T]) { 177 if !(s == nil || elements == nil) { 178 elements.ForEach(s.AddOne) 179 } 180 } 181 182 // AddAllNew inserts elements from the "other" collection if they are not contained in the collection 183 func (s *Set[T]) AddAllNew(other c.ForEach[T]) (ok bool) { 184 if !(s == nil || other == nil) { 185 other.ForEach(func(element T) { ok = s.AddOneNew(element) || ok }) 186 } 187 return ok 188 } 189 190 // Delete removes elements from the collection 191 func (s *Set[T]) Delete(elements ...T) { 192 if s != nil { 193 for _, element := range elements { 194 s.DeleteOne(element) 195 } 196 } 197 } 198 199 // DeleteOne removes an element from the collection 200 func (s *Set[T]) DeleteOne(element T) { 201 if s != nil { 202 delete(s.elements, element) 203 } 204 } 205 206 // DeleteActual removes elements only if they are contained in the collection 207 func (s *Set[T]) DeleteActual(elements ...T) bool { 208 if s == nil { 209 return false 210 } 211 ok := false 212 for i := range elements { 213 ok = s.DeleteActualOne(elements[i]) || ok 214 } 215 return ok 216 } 217 218 // DeleteActualOne removes an element only if it is contained in the collection 219 func (s *Set[T]) DeleteActualOne(element T) (ok bool) { 220 if !(s == nil || s.elements == nil) { 221 if _, ok = s.elements[element]; ok { 222 delete(s.elements, element) 223 } 224 } 225 return ok 226 } 227 228 // For applies the 'consumer' function for the elements until the consumer returns the c.Break to stop. 229 func (s *Set[T]) For(consumer func(T) error) error { 230 if s == nil { 231 return nil 232 } 233 return map_.ForKeys(s.elements, consumer) 234 } 235 236 // ForEach applies the 'consumer' function for every element 237 func (s *Set[T]) ForEach(consumer func(T)) { 238 if s != nil { 239 map_.ForEachKey(s.elements, consumer) 240 } 241 } 242 243 // Filter returns a loop consisting of elements that satisfy the condition of the 'predicate' function 244 func (s *Set[T]) Filter(predicate func(T) bool) loop.Loop[T] { 245 return loop.Filter(s.Loop(), predicate) 246 } 247 248 // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function 249 func (s Set[T]) Filt(predicate func(T) (bool, error)) breakLoop.Loop[T] { 250 return loop.Filt(s.Loop(), predicate) 251 } 252 253 // Convert returns a loop that applies the 'converter' function to the collection elements 254 func (s *Set[T]) Convert(converter func(T) T) loop.Loop[T] { 255 return loop.Convert(s.Loop(), converter) 256 } 257 258 // Conv returns a breakable loop that applies the 'converter' function to the collection elements 259 func (s *Set[T]) Conv(converter func(T) (T, error)) breakLoop.Loop[T] { 260 return loop.Conv(s.Loop(), converter) 261 } 262 263 // Reduce reduces the elements into an one using the 'merge' function 264 func (s *Set[T]) Reduce(merge func(T, T) T) (t T) { 265 if s != nil { 266 t, _ = map_.Reduce(s.elements, func(t1, t2 T, _, _ struct{}) (t T, out struct{}) { 267 return merge(t1, t2), out 268 }) 269 } 270 return t 271 } 272 273 // HasAny finds the first element that satisfies the 'predicate' function condition and returns true if successful 274 func (s *Set[K]) HasAny(predicate func(K) bool) bool { 275 if s != nil { 276 return map_.HasAny(s.elements, func(k K, _ struct{}) bool { 277 return predicate(k) 278 }) 279 } 280 return false 281 } 282 283 // Sort transforms to the ordered Set contains sorted elements 284 func (s *Set[T]) Sort(comparer slice.Comparer[T]) *ordered.Set[T] { 285 if s != nil { 286 return ordered.NewSet(slice.Sort(s.Slice(), comparer)...) 287 } 288 return nil 289 } 290 291 // StableSort transforms to the ordered Set contains sorted elements 292 func (s *Set[T]) StableSort(comparer slice.Comparer[T]) *ordered.Set[T] { 293 if s != nil { 294 return ordered.NewSet(slice.StableSort(s.Slice(), comparer)...) 295 } 296 return nil 297 } 298 299 func (s *Set[T]) String() string { 300 return slice.ToString(s.Slice()) 301 }