github.com/kaydxh/golang@v0.0.131/go/container/set/set.interface.go (about) 1 /* 2 *Copyright (c) 2022, kaydxh 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining a copy 5 *of this software and associated documentation files (the "Software"), to deal 6 *in the Software without restriction, including without limitation the rights 7 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 *copies of the Software, and to permit persons to whom the Software is 9 *furnished to do so, subject to the following conditions: 10 * 11 *The above copyright notice and this permission notice shall be included in all 12 *copies or substantial portions of the Software. 13 * 14 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 *SOFTWARE. 21 */ 22 package set 23 24 import ( 25 "encoding/json" 26 "reflect" 27 "sort" 28 ) 29 30 // sets.Object is a set of Objects, implemented via map[Object]struct{} for minimal memory consumption. 31 type Object map[interface{}]Empty 32 33 // NewObject creates a Object from a list of values. 34 func NewObject(items ...interface{}) Object { 35 ss := Object{} 36 ss.Insert(items...) 37 return ss 38 } 39 40 // ObjectKeySet creates a Object from a keys of a map[Object](? extends interface{}). 41 // If the value passed in is not actually a map, this will panic. 42 func KeySet(theMap interface{}) Object { 43 v := reflect.ValueOf(theMap) 44 ret := Object{} 45 46 for _, keyValue := range v.MapKeys() { 47 ret.Insert(keyValue.Interface().(Object)) 48 } 49 return ret 50 } 51 52 // Insert adds items to the set. 53 func (s Object) Insert(items ...interface{}) Object { 54 for _, item := range items { 55 s[item] = Empty{} 56 } 57 return s 58 } 59 60 // Delete removes all items from the set. 61 func (s Object) Delete(items ...interface{}) Object { 62 for _, item := range items { 63 delete(s, item) 64 } 65 return s 66 } 67 68 // Has returns true if and only if item is contained in the set. 69 func (s Object) Has(item interface{}) bool { 70 _, contained := s[item] 71 return contained 72 } 73 74 // HasAll returns true if and only if all items are contained in the set. 75 func (s Object) HasAll(items ...interface{}) bool { 76 for _, item := range items { 77 if !s.Has(item) { 78 return false 79 } 80 } 81 return true 82 } 83 84 // HasAny returns true if any items are contained in the set. 85 func (s Object) HasAny(items ...interface{}) bool { 86 for _, item := range items { 87 if s.Has(item) { 88 return true 89 } 90 } 91 return false 92 } 93 94 // Difference returns a set of objects that are not in s2 95 // For example: 96 // s1 = {a1, a2, a3} 97 // s2 = {a1, a2, a4, a5} 98 // s1.Difference(s2) = {a3} 99 // s2.Difference(s1) = {a4, a5} 100 func (s Object) Difference(s2 Object) Object { 101 result := NewObject() 102 for key := range s { 103 if !s2.Has(key) { 104 result.Insert(key) 105 } 106 } 107 return result 108 } 109 110 // Union returns a new set which includes items in either s1 or s2. 111 // For example: 112 // s1 = {a1, a2} 113 // s2 = {a3, a4} 114 // s1.Union(s2) = {a1, a2, a3, a4} 115 // s2.Union(s1) = {a1, a2, a3, a4} 116 func (s1 Object) Union(s2 Object) Object { 117 result := NewObject() 118 for key := range s1 { 119 result.Insert(key) 120 } 121 for key := range s2 { 122 result.Insert(key) 123 } 124 return result 125 } 126 127 // Intersection returns a new set which includes the item in BOTH s1 and s2 128 // For example: 129 // s1 = {a1, a2} 130 // s2 = {a2, a3} 131 // s1.Intersection(s2) = {a2} 132 func (s1 Object) Intersection(s2 Object) Object { 133 var walk, other Object 134 result := NewObject() 135 if s1.Len() < s2.Len() { 136 walk = s1 137 other = s2 138 } else { 139 walk = s2 140 other = s1 141 } 142 for key := range walk { 143 if other.Has(key) { 144 result.Insert(key) 145 } 146 } 147 return result 148 } 149 150 // IsSuperset returns true if and only if s1 is a superset of s2. 151 func (s1 Object) IsSuperset(s2 Object) bool { 152 for item := range s2 { 153 if !s1.Has(item) { 154 return false 155 } 156 } 157 return true 158 } 159 160 // Equal returns true if and only if s1 is equal (as a set) to s2. 161 // Two sets are equal if their membership is identical. 162 // (In practice, this means same elements, order doesn't matter) 163 func (s1 Object) Equal(s2 Object) bool { 164 return len(s1) == len(s2) && s1.IsSuperset(s2) 165 } 166 167 type sortableSliceOfObject []interface{} 168 169 func (s sortableSliceOfObject) Len() int { return len(s) } 170 func (s sortableSliceOfObject) Less(i, j int) bool { return lessObject(s[i], s[j]) } 171 func (s sortableSliceOfObject) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 172 173 // List returns the contents as a sorted Object slice. 174 func (s Object) List() []interface{} { 175 res := make(sortableSliceOfObject, 0, len(s)) 176 for key := range s { 177 res = append(res, key) 178 } 179 sort.Sort(res) 180 return []interface{}(res) 181 } 182 183 // UnsortedList returns the slice with contents in random order. 184 func (s Object) UnsortedList() []interface{} { 185 res := make([]interface{}, 0, len(s)) 186 for key := range s { 187 res = append(res, key) 188 } 189 return res 190 } 191 192 // Returns a single element from the set. 193 func (s Object) PopAny() (interface{}, bool) { 194 for key := range s { 195 s.Delete(key) 196 return key, true 197 } 198 var zeroValue Object 199 return zeroValue, false 200 } 201 202 // Len returns the size of the set. 203 func (s Object) Len() int { 204 return len(s) 205 } 206 207 type Lesser interface { 208 Less(a interface{}, b interface{}) bool 209 } 210 211 /* 212 func lessObject(lhs, rhs interface{}) bool { 213 if lhs == nil { 214 return false 215 } 216 217 if rhs == nil { 218 return true 219 } 220 221 switch lhs := lhs.(type) { 222 case nil: 223 return false 224 225 case *string: 226 rhs, ok := rhs.(*string) 227 if !ok { 228 return false 229 } 230 231 return lhs != nil && rhs != nil && *lhs < *rhs 232 233 case *[]byte: 234 rhs, ok := rhs.(*[]byte) 235 if !ok { 236 return false 237 } 238 return lhs != nil && rhs != nil && string(*lhs) < string(*rhs) 239 240 case *int: 241 rhs, ok := rhs.(*int) 242 if !ok { 243 return false 244 } 245 return lhs != nil && rhs != nil && *lhs < *rhs 246 247 case *int32: 248 rhs, ok := rhs.(*int32) 249 if !ok { 250 return false 251 } 252 return lhs != nil && rhs != nil && *lhs < *rhs 253 254 case *uint32: 255 rhs, ok := rhs.(*uint32) 256 if !ok { 257 return false 258 } 259 return lhs != nil && rhs != nil && *lhs < *rhs 260 261 case *int64: 262 rhs, ok := rhs.(*int64) 263 if !ok { 264 return false 265 } 266 return lhs != nil && rhs != nil && *lhs < *rhs 267 268 case *uint64: 269 rhs, ok := rhs.(*uint64) 270 if !ok { 271 return false 272 } 273 return lhs != nil && rhs != nil && *lhs < *rhs 274 275 case *float32: 276 rhs, ok := rhs.(*float32) 277 if !ok { 278 return false 279 } 280 return lhs != nil && rhs != nil && *lhs < *rhs 281 282 case *float64: 283 rhs, ok := rhs.(*float64) 284 if !ok { 285 return false 286 } 287 return lhs != nil && rhs != nil && *lhs < *rhs 288 289 290 default: 291 var ll Lesser 292 ll, ok = lhs.(Lesser) 293 if !ok { 294 295 } 296 297 var err error 298 jb, err = json.Marshal(v) 299 if err != nil { 300 return nil, fmt.Errorf("jsonpb.Marshal: %v", err) 301 } 302 303 } 304 return false 305 } 306 */ 307 308 func lessObject(lhs, rhs interface{}) bool { 309 jbl, err := json.Marshal(lhs) 310 if err != nil { 311 return false 312 } 313 jbr, err := json.Marshal(rhs) 314 if err != nil { 315 return false 316 } 317 318 return string(jbl) < string(jbr) 319 } 320 321 /* 322 func LessObject(lhs, rhs interface{}) bool { 323 jbl, err := json.Marshal(lhs) 324 if err != nil { 325 return false 326 } 327 jbr, err := json.Marshal(rhs) 328 if err != nil { 329 return false 330 } 331 332 return string(jbl) < string(jbr) 333 } 334 */