github.com/blend/go-sdk@v1.20220411.3/collections/set.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package collections 9 10 import ( 11 "strconv" 12 "strings" 13 ) 14 15 // NewSetOfInt creates a new SetOfInt. 16 func NewSetOfInt(values ...int) SetOfInt { 17 set := SetOfInt{} 18 for _, v := range values { 19 set.Add(v) 20 } 21 return set 22 } 23 24 // SetOfInt is a type alias for map[int]int 25 type SetOfInt map[int]bool 26 27 // Add adds an element to the set, replaceing a previous value. 28 func (si SetOfInt) Add(i int) { 29 si[i] = true 30 } 31 32 // Remove removes an element from the set. 33 func (si SetOfInt) Remove(i int) { 34 delete(si, i) 35 } 36 37 // Contains returns if the element is in the set. 38 func (si SetOfInt) Contains(i int) bool { 39 _, ok := si[i] 40 return ok 41 } 42 43 // Len returns the number of elements in the set. 44 func (si SetOfInt) Len() int { 45 return len(si) 46 } 47 48 // Copy returns a new copy of the set. 49 func (si SetOfInt) Copy() SetOfInt { 50 newSet := NewSetOfInt() 51 for key := range si { 52 newSet.Add(key) 53 } 54 return newSet 55 } 56 57 // Union joins two sets together without dupes. 58 func (si SetOfInt) Union(other SetOfInt) SetOfInt { 59 union := NewSetOfInt() 60 for k := range si { 61 union.Add(k) 62 } 63 64 for k := range other { 65 union.Add(k) 66 } 67 return union 68 } 69 70 // Intersect returns shared elements between two sets. 71 func (si SetOfInt) Intersect(other SetOfInt) SetOfInt { 72 intersection := NewSetOfInt() 73 for k := range si { 74 if other.Contains(k) { 75 intersection.Add(k) 76 } 77 } 78 return intersection 79 } 80 81 // Difference returns non-shared elements between two sets. 82 func (si SetOfInt) Difference(other SetOfInt) SetOfInt { 83 difference := NewSetOfInt() 84 for k := range si { 85 if !other.Contains(k) { 86 difference.Add(k) 87 } 88 } 89 for k := range other { 90 if !si.Contains(k) { 91 difference.Add(k) 92 } 93 } 94 return difference 95 } 96 97 // IsSubsetOf returns if a given set is a complete subset of another set, 98 // i.e. all elements in target set are in other set. 99 func (si SetOfInt) IsSubsetOf(other SetOfInt) bool { 100 for k := range si { 101 if !other.Contains(k) { 102 return false 103 } 104 } 105 return true 106 } 107 108 // AsSlice returns the set as a slice. 109 func (si SetOfInt) AsSlice() []int { 110 output := []int{} 111 for key := range si { 112 output = append(output, key) 113 } 114 return output 115 } 116 117 // String returns the set as a csv string. 118 func (si SetOfInt) String() string { 119 var values []string 120 for _, i := range si.AsSlice() { 121 values = append(values, strconv.Itoa(i)) 122 } 123 124 return strings.Join(values, ", ") 125 } 126 127 // NewSetOfString creates a new SetOfString. 128 func NewSetOfString(values ...string) SetOfString { 129 set := SetOfString{} 130 for _, v := range values { 131 set.Add(v) 132 } 133 return set 134 } 135 136 // SetOfString is a set of strings 137 type SetOfString map[string]bool 138 139 // Add adds an element. 140 func (ss SetOfString) Add(entry string) { 141 if _, hasEntry := ss[entry]; !hasEntry { 142 ss[entry] = true 143 } 144 } 145 146 // Remove deletes an element, returns if the element was in the set. 147 func (ss SetOfString) Remove(entry string) bool { 148 if _, hasEntry := ss[entry]; hasEntry { 149 delete(ss, entry) 150 return true 151 } 152 return false 153 } 154 155 // Contains returns if an element is in the set. 156 func (ss SetOfString) Contains(entry string) bool { 157 _, hasEntry := ss[entry] 158 return hasEntry 159 } 160 161 // Len returns the length of the set. 162 func (ss SetOfString) Len() int { 163 return len(ss) 164 } 165 166 // Copy returns a new copy of the set. 167 func (ss SetOfString) Copy() SetOfString { 168 newSet := SetOfString{} 169 for key := range ss { 170 newSet.Add(key) 171 } 172 return newSet 173 } 174 175 // Union joins two sets together without dupes. 176 func (ss SetOfString) Union(other SetOfString) SetOfString { 177 union := NewSetOfString() 178 for k := range ss { 179 union.Add(k) 180 } 181 182 for k := range other { 183 union.Add(k) 184 } 185 return union 186 } 187 188 // Intersect returns shared elements between two sets. 189 func (ss SetOfString) Intersect(other SetOfString) SetOfString { 190 intersection := NewSetOfString() 191 for k := range ss { 192 if other.Contains(k) { 193 intersection.Add(k) 194 } 195 } 196 return intersection 197 } 198 199 // Difference returns non-shared elements between two sets. 200 func (ss SetOfString) Difference(other SetOfString) SetOfString { 201 difference := NewSetOfString() 202 for k := range ss { 203 if !other.Contains(k) { 204 difference.Add(k) 205 } 206 } 207 for k := range other { 208 if !ss.Contains(k) { 209 difference.Add(k) 210 } 211 } 212 return difference 213 } 214 215 // IsSubsetOf returns if a given set is a complete subset of another set, 216 // i.e. all elements in target set are in other set. 217 func (ss SetOfString) IsSubsetOf(other SetOfString) bool { 218 for k := range ss { 219 if !other.Contains(k) { 220 return false 221 } 222 } 223 return true 224 } 225 226 // AsSlice returns the set as a slice. 227 func (ss SetOfString) AsSlice() []string { 228 output := []string{} 229 for key := range ss { 230 output = append(output, key) 231 } 232 return output 233 } 234 235 // String returns the set as a csv string. 236 func (ss SetOfString) String() string { 237 return strings.Join(ss.AsSlice(), ", ") 238 }