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