hashset.go (4004B)
1 package hashset 2 3 import "errors" 4 5 type HashSet[V comparable] struct { 6 items map[V]struct{} 7 } 8 9 func New[V comparable]() *HashSet[V] { 10 h := new(HashSet[V]) 11 h.items = make(map[V]struct{}) 12 return h 13 } 14 15 func (h *HashSet[V]) Set(v V) { 16 h.items[v] = struct{}{} 17 } 18 19 // Insert adds a value to the set. 20 // If the set did not have this value present, true is returned. 21 // If the set did have this value present, false is returned. 22 func (h *HashSet[V]) Insert(v V) bool { 23 if h.Contains(v) { 24 return false 25 } 26 h.items[v] = struct{}{} 27 return true 28 } 29 30 // Contains returns true if the set contains a value. 31 func (h *HashSet[V]) Contains(v V) bool { 32 _, found := h.items[v] 33 return found 34 } 35 36 // Len returns the number of elements in the set. 37 func (h *HashSet[V]) Len() int { 38 return len(h.items) 39 } 40 41 func (h *HashSet[V]) Empty() bool { 42 return len(h.items) == 0 43 } 44 45 // Clear clears the set, removing all values. 46 func (h *HashSet[V]) Clear() { 47 h.items = make(map[V]struct{}) 48 } 49 50 // Difference visits the values representing the difference, i.e., the values that are in self but not in other. 51 func (h *HashSet[V]) Difference(other *HashSet[V]) *HashSet[V] { 52 n := New[V]() 53 for k, v := range h.items { 54 if !other.Contains(k) { 55 n.items[k] = v 56 } 57 } 58 return n 59 } 60 61 // SymmetricDifference visits the values representing the symmetric difference, i.e., the values that are in self or in other but not in both. 62 func (h *HashSet[V]) SymmetricDifference(other *HashSet[V]) *HashSet[V] { 63 n := New[V]() 64 for k, v := range h.items { 65 if !other.Contains(k) { 66 n.items[k] = v 67 } 68 } 69 for k, v := range other.items { 70 if !h.Contains(k) { 71 n.items[k] = v 72 } 73 } 74 return n 75 } 76 77 // Intersection visits the values representing the intersection, i.e., the values that are both in self and other. 78 func (h *HashSet[V]) Intersection(other *HashSet[V]) *HashSet[V] { 79 n := New[V]() 80 for k, v := range h.items { 81 if other.Contains(k) { 82 n.items[k] = v 83 } 84 } 85 return n 86 } 87 88 // Union visits the values representing the union, i.e., all the values in self or other, without duplicates. 89 func (h *HashSet[V]) Union(other *HashSet[V]) *HashSet[V] { 90 n := New[V]() 91 for k, v := range h.items { 92 n.items[k] = v 93 } 94 for k, v := range other.items { 95 n.items[k] = v 96 } 97 return n 98 } 99 100 // Get returns a reference to the value in the set, if any, that is equal to the given value. 101 func (h *HashSet[V]) Get(v V) (out V, err error) { 102 if !h.Contains(v) { 103 return out, errors.New("item not found") 104 } 105 return v, nil 106 } 107 108 // IsSubset returns true if the set is a subset of another, i.e., other contains at least all the values in self. 109 func (h *HashSet[V]) IsSubset(other *HashSet[V]) bool { 110 for k := range h.items { 111 if !other.Contains(k) { 112 return false 113 } 114 } 115 return true 116 } 117 118 // IsSuperset returns true if the set is a superset of another, i.e., self contains at least all the values in other. 119 func (h *HashSet[V]) IsSuperset(other *HashSet[V]) bool { 120 for k := range other.items { 121 if !h.Contains(k) { 122 return false 123 } 124 } 125 return true 126 } 127 128 // Replace adds a value to the set, replacing the existing value, if any, that is equal to the given one. Returns the replaced value. 129 func (h *HashSet[V]) Replace(v V) (V, bool) { 130 var zero V 131 if h.Contains(v) { 132 return v, true 133 } 134 h.items[v] = struct{}{} 135 return zero, false 136 } 137 138 // Remove a value from the set. Returns whether the value was present in the set. 139 func (h *HashSet[V]) Remove(v V) bool { 140 if !h.Contains(v) { 141 return false 142 } 143 delete(h.items, v) 144 return true 145 } 146 147 func (h *HashSet[V]) Delete(v V) { 148 delete(h.items, v) 149 } 150 151 // Take removes and returns the value in the set, if any, that is equal to the given one. 152 func (h *HashSet[V]) Take(v V) (out V, err error) { 153 if !h.Contains(v) { 154 return out, errors.New("item not found") 155 } 156 delete(h.items, v) 157 return v, nil 158 } 159 160 func (h *HashSet[V]) Each(clb func(V)) { 161 for k := range h.items { 162 clb(k) 163 } 164 } 165 166 func (h *HashSet[V]) ToArray() []V { 167 out := make([]V, len(h.items)) 168 i := 0 169 for k := range h.items { 170 out[i] = k 171 i++ 172 } 173 return out 174 }