github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/collection/immutable/set.go (about) 1 package immutable 2 3 import ( 4 "fmt" 5 6 breakLoop "github.com/m4gshm/gollections/break/loop" 7 "github.com/m4gshm/gollections/collection" 8 "github.com/m4gshm/gollections/collection/immutable/ordered" 9 "github.com/m4gshm/gollections/loop" 10 "github.com/m4gshm/gollections/map_" 11 "github.com/m4gshm/gollections/slice" 12 ) 13 14 // WrapSet creates a set using a map as the internal storage. 15 func WrapSet[T comparable](elements map[T]struct{}) Set[T] { 16 return Set[T]{elements: elements} 17 } 18 19 // Set is a collection implementation that provides storage for unique elements, prevents duplication. The elements must be comparable. 20 type Set[T comparable] struct { 21 elements map[T]struct{} 22 } 23 24 var ( 25 _ collection.Set[int] = (*Set[int])(nil) 26 _ collection.Set[int] = Set[int]{} 27 _ fmt.Stringer = (*Set[int])(nil) 28 _ fmt.Stringer = Set[int]{} 29 ) 30 31 // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled. 32 func (s Set[T]) All(consumer func(T) bool) { 33 map_.TrackKeysWhile(s.elements, consumer) 34 } 35 36 // Loop creates a loop to iterate through the collection. 37 func (s Set[T]) Loop() loop.Loop[T] { 38 h := s.Head() 39 return (&h).Next 40 } 41 42 // Deprecated: Head is deprecated. Will be replaced by rance-over function iterator. 43 // Head creates an iterator to iterate through the collection. 44 func (s Set[T]) Head() map_.KeyIter[T, struct{}] { 45 return map_.NewKeyIter(s.elements) 46 } 47 48 // Deprecated: First is deprecated. Will be replaced by rance-over function iterator. 49 // First returns the first element of the collection, an iterator to iterate over the remaining elements, and true\false marker of availability next elements. 50 // If no more elements then ok==false. 51 func (s Set[T]) First() (map_.KeyIter[T, struct{}], T, bool) { 52 var ( 53 iterator = s.Head() 54 first, ok = iterator.Next() 55 ) 56 return iterator, first, ok 57 } 58 59 // Slice collects the elements to a slice 60 func (s Set[T]) Slice() []T { 61 return map_.Keys(s.elements) 62 } 63 64 // Append collects the values to the specified 'out' slice 65 func (s Set[T]) Append(out []T) []T { 66 return map_.AppendKeys(s.elements, out) 67 } 68 69 // Len returns amount of elements 70 func (s Set[T]) Len() int { 71 return len(s.elements) 72 } 73 74 // IsEmpty returns true if the collection is empty 75 func (s Set[T]) IsEmpty() bool { 76 return s.Len() == 0 77 } 78 79 // For applies the 'consumer' function for the elements until the consumer returns the c.Break to stop. 80 func (s Set[T]) For(consumer func(T) error) error { 81 82 return map_.ForKeys(s.elements, consumer) 83 } 84 85 // ForEach applies the 'consumer' function for every element 86 func (s Set[T]) ForEach(consumer func(T)) { 87 map_.ForEachKey(s.elements, consumer) 88 } 89 90 // Filter returns a loop consisting of elements that satisfy the condition of the 'predicate' function 91 func (s Set[T]) Filter(predicate func(T) bool) loop.Loop[T] { 92 return loop.Filter(s.Loop(), predicate) 93 } 94 95 // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function 96 func (s Set[T]) Filt(predicate func(T) (bool, error)) breakLoop.Loop[T] { 97 return loop.Filt(s.Loop(), predicate) 98 } 99 100 // Convert returns a loop that applies the 'converter' function to the collection elements 101 func (s Set[T]) Convert(converter func(T) T) loop.Loop[T] { 102 return loop.Convert(s.Loop(), converter) 103 } 104 105 // Conv returns a breakable loop that applies the 'converter' function to the collection elements 106 func (s Set[T]) Conv(converter func(T) (T, error)) breakLoop.Loop[T] { 107 return loop.Conv(s.Loop(), converter) 108 } 109 110 // Reduce reduces the elements into an one using the 'merge' function 111 func (s Set[T]) Reduce(merge func(T, T) T) T { 112 t, _ := map_.Reduce(s.elements, func(t1, t2 T, _, _ struct{}) (t T, out struct{}) { 113 return merge(t1, t2), out 114 }) 115 return t 116 } 117 118 // HasAny finds the first element that satisfies the 'predicate' function condition and returns true if successful 119 func (s Set[T]) HasAny(predicate func(T) bool) bool { 120 return map_.HasAny(s.elements, func(t T, _ struct{}) bool { 121 return predicate(t) 122 }) 123 } 124 125 // Contains checks is the collection contains an element 126 func (s Set[T]) Contains(element T) (ok bool) { 127 if elements := s.elements; elements != nil { 128 _, ok = elements[element] 129 } 130 return ok 131 } 132 133 // Sort transforms to the ordered set with sorted elements 134 func (s Set[T]) Sort(comparer slice.Comparer[T]) ordered.Set[T] { 135 return s.sortBy(slice.Sort, comparer) 136 } 137 138 // StableSort transforms to the ordered set with sorted elements 139 func (s Set[T]) StableSort(comparer slice.Comparer[T]) ordered.Set[T] { 140 return s.sortBy(slice.StableSort, comparer) 141 } 142 143 func (s Set[T]) sortBy(sorter func([]T, slice.Comparer[T]) []T, comparer slice.Comparer[T]) ordered.Set[T] { 144 return ordered.WrapSet(sorter(s.Slice(), comparer), s.elements) 145 } 146 147 func (s Set[T]) String() string { 148 return slice.ToString(s.Slice()) 149 }