github.com/blend/go-sdk@v1.20240719.1/collections/set.go (about) 1 /* 2 3 Copyright (c) 2024 - 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 "fmt" 12 "strings" 13 ) 14 15 // NewSet creates a new set from a list of values. 16 func NewSet[T comparable](values ...T) Set[T] { 17 output := Set[T](make(map[T]struct{})) 18 for _, v := range values { 19 output[v] = struct{}{} 20 } 21 return output 22 } 23 24 // Set is a generic implementation of a set data structure. 25 type Set[T comparable] map[T]struct{} 26 27 // Add adds an element to the set, replacing a previous value. 28 func (s Set[T]) Add(i T) { 29 s[i] = struct{}{} 30 } 31 32 // Remove removes an element from the set. 33 func (s Set[T]) Remove(i T) { 34 delete(s, i) 35 } 36 37 // Contains returns if the element is in the set. 38 func (s Set[T]) Contains(i T) bool { 39 _, ok := s[i] 40 return ok 41 } 42 43 // Len returns the number of elements in the set. 44 func (s Set[T]) Len() int { 45 return len(s) 46 } 47 48 // Copy returns a new copy of the set. 49 func (s Set[T]) Copy() Set[T] { 50 newSet := NewSet[T]() 51 for key := range s { 52 newSet.Add(key) 53 } 54 return newSet 55 } 56 57 // Union joins two sets together without dupes. 58 func (s Set[T]) Union(other Set[T]) Set[T] { 59 union := NewSet[T]() 60 for k := range s { 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 (s Set[T]) Intersect(other Set[T]) Set[T] { 72 intersection := NewSet[T]() 73 for k := range s { 74 if other.Contains(k) { 75 intersection.Add(k) 76 } 77 } 78 return intersection 79 } 80 81 // Subtract removes all elements of `other` set from `s`. 82 func (s Set[T]) Subtract(other Set[T]) Set[T] { 83 subtracted := NewSet[T]() 84 for k := range s { 85 if !other.Contains(k) { 86 subtracted.Add(k) 87 } 88 } 89 return subtracted 90 } 91 92 // Difference returns non-shared elements between two sets. 93 func (s Set[T]) Difference(other Set[T]) Set[T] { 94 difference := NewSet[T]() 95 for k := range s { 96 if !other.Contains(k) { 97 difference.Add(k) 98 } 99 } 100 for k := range other { 101 if !s.Contains(k) { 102 difference.Add(k) 103 } 104 } 105 return difference 106 } 107 108 // IsSubsetOf returns if a given set is a complete subset of another set, 109 // i.e. all elements in target set are in other set. 110 func (s Set[T]) IsSubsetOf(other Set[T]) bool { 111 for k := range s { 112 if !other.Contains(k) { 113 return false 114 } 115 } 116 return true 117 } 118 119 // AsSlice returns the set as a slice. 120 func (s Set[T]) AsSlice() []T { 121 var output []T 122 for key := range s { 123 output = append(output, key) 124 } 125 return output 126 } 127 128 // String returns the set as a csv string. 129 func (s Set[T]) String() string { 130 var values []string 131 for key := range s { 132 values = append(values, fmt.Sprint(key)) 133 } 134 return strings.Join(values, ", ") 135 }