github.com/lyft/flytestdlib@v0.3.12-0.20210213045714-8cdd111ecda1/sets/generic_set.go (about) 1 package sets 2 3 import ( 4 "sort" 5 ) 6 7 type SetObject interface { 8 GetID() string 9 } 10 11 type Generic map[string]SetObject 12 13 // New creates a Generic from a list of values. 14 func NewGeneric(items ...SetObject) Generic { 15 gs := Generic{} 16 gs.Insert(items...) 17 return gs 18 } 19 20 // Insert adds items to the set. 21 func (g Generic) Insert(items ...SetObject) { 22 for _, item := range items { 23 g[item.GetID()] = item 24 } 25 } 26 27 // Delete removes all items from the set. 28 func (g Generic) Delete(items ...SetObject) { 29 for _, item := range items { 30 delete(g, item.GetID()) 31 } 32 } 33 34 // Has returns true if and only if item is contained in the set. 35 func (g Generic) Has(item SetObject) bool { 36 _, contained := g[item.GetID()] 37 return contained 38 } 39 40 // HasAll returns true if and only if all items are contained in the set. 41 func (g Generic) HasAll(items ...SetObject) bool { 42 for _, item := range items { 43 if !g.Has(item) { 44 return false 45 } 46 } 47 return true 48 } 49 50 // HasAny returns true if any items are contained in the set. 51 func (g Generic) HasAny(items ...SetObject) bool { 52 for _, item := range items { 53 if g.Has(item) { 54 return true 55 } 56 } 57 return false 58 } 59 60 // Difference returns a set of objects that are not in s2 61 // For example: 62 // s1 = {a1, a2, a3} 63 // s2 = {a1, a2, a4, a5} 64 // s1.Difference(s2) = {a3} 65 // s2.Difference(s1) = {a4, a5} 66 func (g Generic) Difference(g2 Generic) Generic { 67 result := NewGeneric() 68 for _, v := range g { 69 if !g2.Has(v) { 70 result.Insert(v) 71 } 72 } 73 return result 74 } 75 76 // Union returns a new set which includes items in either s1 or s2. 77 // For example: 78 // s1 = {a1, a2} 79 // s2 = {a3, a4} 80 // s1.Union(s2) = {a1, a2, a3, a4} 81 // s2.Union(s1) = {a1, a2, a3, a4} 82 func (g Generic) Union(s2 Generic) Generic { 83 result := NewGeneric() 84 for _, v := range g { 85 result.Insert(v) 86 } 87 for _, v := range s2 { 88 result.Insert(v) 89 } 90 return result 91 } 92 93 // Intersection returns a new set which includes the item in BOTH s1 and s2 94 // For example: 95 // s1 = {a1, a2} 96 // s2 = {a2, a3} 97 // s1.Intersection(s2) = {a2} 98 func (g Generic) Intersection(s2 Generic) Generic { 99 var walk, other Generic 100 result := NewGeneric() 101 if g.Len() < s2.Len() { 102 walk = g 103 other = s2 104 } else { 105 walk = s2 106 other = g 107 } 108 for _, v := range walk { 109 if other.Has(v) { 110 result.Insert(v) 111 } 112 } 113 return result 114 } 115 116 // IsSuperset returns true if and only if s1 is a superset of s2. 117 func (g Generic) IsSuperset(s2 Generic) bool { 118 for _, v := range s2 { 119 if !g.Has(v) { 120 return false 121 } 122 } 123 return true 124 } 125 126 // Equal returns true if and only if s1 is equal (as a set) to s2. 127 // Two sets are equal if their membership is identical. 128 // (In practice, this means same elements, order doesn't matter) 129 func (g Generic) Equal(s2 Generic) bool { 130 return len(g) == len(s2) && g.IsSuperset(s2) 131 } 132 133 type sortableSliceOfGeneric []string 134 135 func (s sortableSliceOfGeneric) Len() int { return len(s) } 136 func (s sortableSliceOfGeneric) Less(i, j int) bool { return lessString(s[i], s[j]) } 137 func (s sortableSliceOfGeneric) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 138 139 // List returns the contents as a sorted string slice. 140 func (g Generic) ListKeys() []string { 141 res := make(sortableSliceOfGeneric, 0, len(g)) 142 for key := range g { 143 res = append(res, key) 144 } 145 sort.Sort(res) 146 return []string(res) 147 } 148 149 // List returns the contents as a sorted string slice. 150 func (g Generic) List() []SetObject { 151 keys := g.ListKeys() 152 res := make([]SetObject, 0, len(keys)) 153 for _, k := range keys { 154 s := g[k] 155 res = append(res, s) 156 } 157 return res 158 } 159 160 // UnsortedList returns the slice with contents in random order. 161 func (g Generic) UnsortedListKeys() []string { 162 res := make([]string, 0, len(g)) 163 for key := range g { 164 res = append(res, key) 165 } 166 return res 167 } 168 169 // UnsortedList returns the slice with contents in random order. 170 func (g Generic) UnsortedList() []SetObject { 171 res := make([]SetObject, 0, len(g)) 172 for _, v := range g { 173 res = append(res, v) 174 } 175 return res 176 } 177 178 // Returns a single element from the set. 179 func (g Generic) PopAny() (SetObject, bool) { 180 for _, v := range g { 181 g.Delete(v) 182 return v, true 183 } 184 var zeroValue SetObject 185 return zeroValue, false 186 } 187 188 // Len returns the size of the set. 189 func (g Generic) Len() int { 190 return len(g) 191 } 192 193 func lessString(lhs, rhs string) bool { 194 return lhs < rhs 195 }