github.com/eframework-cn/EP.GO.UTIL@v1.0.0/xcollect/reflect.go (about) 1 //-----------------------------------------------------------------------// 2 // GNU GENERAL PUBLIC LICENSE // 3 // Version 2, June 1991 // 4 // // 5 // Copyright (C) EFramework, https://eframework.cn, All rights reserved. // 6 // Everyone is permitted to copy and distribute verbatim copies // 7 // of this license document, but changing it is not allowed. // 8 // SEE LICENSE.md FOR MORE DETAILS. // 9 //-----------------------------------------------------------------------// 10 11 package xcollect 12 13 import ( 14 "reflect" 15 16 "github.com/eframework-cn/EP.GO.UTIL/xlog" 17 ) 18 19 // Deprecated: 判断集合是否存在元素 20 // collection: 指针类型的map或slice 21 // compare: 元素或对比函数 22 func Contains(collection interface{}, compare interface{}) bool { 23 if collection == nil || compare == nil { 24 return false 25 } 26 collectionValue := reflect.ValueOf(collection) 27 compareValue := reflect.ValueOf(compare) 28 compareIsFunc := compareValue.Type().Kind() == reflect.Func 29 cKind := collectionValue.Kind() 30 if cKind != reflect.Ptr { 31 xlog.Panic("xcollect.Contains: collection must be pointer, this kind is", cKind) 32 return false 33 } 34 switch collectionValue.Elem().Kind() { 35 case reflect.Slice, reflect.Array: 36 for i := 0; i < collectionValue.Elem().Len(); i++ { 37 obj := collectionValue.Elem().Index(i) 38 ele := obj.Interface() 39 if compareIsFunc { 40 params := []reflect.Value{obj} 41 rets := compareValue.Call(params) 42 if len(rets) == 1 && 43 rets[0].Kind() == reflect.Bool && 44 rets[0].Bool() { 45 return true 46 } 47 } else { 48 if ele == compare { 49 return true 50 } 51 } 52 } 53 case reflect.Map: 54 iter := collectionValue.Elem().MapRange() 55 for iter.Next() { 56 obj := iter.Value() 57 ele := obj.Interface() 58 if compareIsFunc { 59 params := []reflect.Value{obj} 60 rets := compareValue.Call(params) 61 if len(rets) == 1 && 62 rets[0].Kind() == reflect.Bool && 63 rets[0].Bool() { 64 return true 65 } 66 } else { 67 if ele == compare { 68 return true 69 } 70 } 71 } 72 } 73 return false 74 } 75 76 // Deprecated: 从集合中查找元素 77 // collection: 指针类型的map或slice 78 // compare: 元素或对比函数 79 func Find(collection interface{}, compare interface{}) interface{} { 80 if collection == nil || compare == nil { 81 return false 82 } 83 collectionValue := reflect.ValueOf(collection) 84 compareValue := reflect.ValueOf(compare) 85 compareIsFunc := compareValue.Type().Kind() == reflect.Func 86 cKind := collectionValue.Kind() 87 if cKind != reflect.Ptr { 88 xlog.Panic("xcollect.Find: collection must be pointer, this kind is", cKind) 89 return false 90 } 91 switch collectionValue.Elem().Kind() { 92 case reflect.Slice, reflect.Array: 93 for i := 0; i < collectionValue.Elem().Len(); i++ { 94 obj := collectionValue.Elem().Index(i) 95 ele := obj.Interface() 96 if compareIsFunc { 97 params := []reflect.Value{obj} 98 rets := compareValue.Call(params) 99 if len(rets) == 1 && 100 rets[0].Kind() == reflect.Bool && 101 rets[0].Bool() { 102 return ele 103 } 104 } else { 105 if ele == compare { 106 return ele 107 } 108 } 109 } 110 case reflect.Map: 111 iter := collectionValue.Elem().MapRange() 112 for iter.Next() { 113 obj := iter.Value() 114 ele := obj.Interface() 115 if compareIsFunc { 116 params := []reflect.Value{obj} 117 rets := compareValue.Call(params) 118 if len(rets) == 1 && 119 rets[0].Kind() == reflect.Bool && 120 rets[0].Bool() { 121 return ele 122 } 123 } else { 124 if ele == compare { 125 return ele 126 } 127 } 128 } 129 return nil 130 } 131 return nil 132 } 133 134 // Deprecated: 从集合中索引元素 135 // collection: 指针类型的map或slice 136 // compare: 元素或对比函数 137 // return: slice-number, map-key 138 func Index(collection interface{}, compare interface{}) interface{} { 139 if collection == nil || compare == nil { 140 return false 141 } 142 collectionValue := reflect.ValueOf(collection) 143 compareValue := reflect.ValueOf(compare) 144 compareIsFunc := compareValue.Type().Kind() == reflect.Func 145 cKind := collectionValue.Kind() 146 if cKind != reflect.Ptr { 147 xlog.Panic("xcollect.Index: collection must be pointer, this kind is", cKind) 148 return false 149 } 150 switch collectionValue.Elem().Kind() { 151 case reflect.Slice, reflect.Array: 152 for i := 0; i < collectionValue.Elem().Len(); i++ { 153 obj := collectionValue.Elem().Index(i) 154 ele := obj.Interface() 155 if compareIsFunc { 156 params := []reflect.Value{obj} 157 rets := compareValue.Call(params) 158 if len(rets) == 1 && 159 rets[0].Kind() == reflect.Bool && 160 rets[0].Bool() { 161 return i 162 } 163 } else { 164 if ele == compare { 165 return i 166 } 167 } 168 } 169 return -1 170 case reflect.Map: 171 iter := collectionValue.Elem().MapRange() 172 for iter.Next() { 173 obj := iter.Value() 174 ele := obj.Interface() 175 if compareIsFunc { 176 params := []reflect.Value{obj} 177 rets := compareValue.Call(params) 178 if len(rets) == 1 && 179 rets[0].Kind() == reflect.Bool && 180 rets[0].Bool() { 181 return iter.Key().Interface() 182 } 183 } else { 184 if ele == compare { 185 return iter.Key().Interface() 186 } 187 } 188 } 189 } 190 return nil 191 } 192 193 // Deprecated: 在集合中新增元素 194 // collection: 指针类型的slice 195 // element: 元素 196 func Append(collection interface{}, element interface{}) bool { 197 if collection == nil || element == nil { 198 return false 199 } 200 collectionValue := reflect.ValueOf(collection) 201 cKind := collectionValue.Kind() 202 if cKind != reflect.Ptr { 203 xlog.Panic("xcollect.Append: collection must be pointer, this kind is", cKind) 204 return false 205 } 206 switch collectionValue.Elem().Kind() { 207 case reflect.Slice, reflect.Array: 208 array := []reflect.Value{reflect.ValueOf(element)} 209 nslice := reflect.Append(collectionValue.Elem(), array...) 210 collectionValue.Elem().Set(nslice) 211 return true 212 case reflect.Map: 213 } 214 return false 215 } 216 217 // Deprecated: 从集合中移除元素 218 // collection: 指针类型的map或slice 219 // compare: 元素或对比函数 220 func Remove(collection interface{}, compare interface{}) bool { 221 if collection == nil || compare == nil { 222 return false 223 } 224 collectionValue := reflect.ValueOf(collection) 225 compareValue := reflect.ValueOf(compare) 226 compareIsFunc := compareValue.Type().Kind() == reflect.Func 227 cKind := collectionValue.Kind() 228 if cKind != reflect.Ptr { 229 xlog.Panic("xcollect.Remove: collection must be pointer, this kind is", cKind) 230 return false 231 } 232 switch collectionValue.Elem().Kind() { 233 case reflect.Slice, reflect.Array: 234 array := make([]reflect.Value, 0) 235 sigRet := false 236 for i := 0; i < collectionValue.Elem().Len(); i++ { 237 obj := collectionValue.Elem().Index(i) 238 ele := obj.Interface() 239 if compareIsFunc { 240 params := []reflect.Value{obj} 241 rets := compareValue.Call(params) 242 if len(rets) == 1 && 243 rets[0].Kind() == reflect.Bool && 244 rets[0].Bool() { 245 sigRet = true 246 } else { 247 array = append(array, obj) 248 } 249 } else { 250 if ele == compare { 251 sigRet = true 252 } else { 253 array = append(array, obj) 254 } 255 } 256 } 257 nslice := reflect.MakeSlice(collectionValue.Type().Elem(), 0, 0) 258 nslice = reflect.Append(nslice, array...) 259 collectionValue.Elem().Set(nslice) 260 return sigRet 261 case reflect.Map: 262 iter := collectionValue.Elem().MapRange() 263 for iter.Next() { 264 obj := iter.Value() 265 ele := obj.Interface() 266 if compareIsFunc { 267 params := []reflect.Value{obj} 268 rets := compareValue.Call(params) 269 if len(rets) == 1 && 270 rets[0].Kind() == reflect.Bool && 271 rets[0].Bool() { 272 collectionValue.Elem().SetMapIndex(iter.Key(), reflect.Value{}) 273 return true 274 } 275 } else { 276 if ele == compare { 277 collectionValue.Elem().SetMapIndex(iter.Key(), reflect.Value{}) 278 return true 279 } 280 } 281 } 282 } 283 return false 284 } 285 286 // Deprecated: 从集合中移除元素 287 // collection: 支持指针类型的map或slice 288 // compare: 索引或key 289 func Delete(collection interface{}, compare interface{}) bool { 290 if collection == nil || compare == nil { 291 return false 292 } 293 collectionValue := reflect.ValueOf(collection) 294 compareValue := reflect.ValueOf(compare) 295 cKind := collectionValue.Kind() 296 if cKind != reflect.Ptr { 297 xlog.Panic("xcollect.Delete: collection must be pointer, this kind is", cKind) 298 return false 299 } 300 switch collectionValue.Elem().Kind() { 301 case reflect.Slice, reflect.Array: 302 sigRet := false 303 switch compare.(type) { 304 case int, int32, int64, uint32, uint64, 305 int16, uint16, int8, uint8: 306 compareI := -1 307 switch compare.(type) { 308 case int: 309 compareI = compare.(int) 310 break 311 case int32: 312 compareI = int(compare.(int32)) 313 break 314 case int64: 315 compareI = int(compare.(int64)) 316 break 317 case uint32: 318 compareI = int(compare.(uint32)) 319 break 320 case uint64: 321 compareI = int(compare.(uint64)) 322 break 323 case int16: 324 compareI = int(compare.(int16)) 325 break 326 case uint16: 327 compareI = int(compare.(uint16)) 328 break 329 case int8: 330 compareI = int(compare.(int8)) 331 break 332 case uint8: 333 compareI = int(compare.(uint8)) 334 break 335 } 336 array := make([]reflect.Value, 0) 337 for i := 0; i < collectionValue.Elem().Len(); i++ { 338 obj := collectionValue.Elem().Index(i) 339 if i == compareI { 340 sigRet = true 341 } else { 342 array = append(array, obj) 343 } 344 } 345 nslice := reflect.MakeSlice(collectionValue.Type().Elem(), 0, 0) 346 nslice = reflect.Append(nslice, array...) 347 collectionValue.Elem().Set(nslice) 348 break 349 default: 350 xlog.Panic("xcollect.Delete: compare of slice must be interger") 351 break 352 } 353 return sigRet 354 case reflect.Map: 355 value := collectionValue.Elem().MapIndex(compareValue) 356 if value.IsValid() { 357 collectionValue.Elem().SetMapIndex(compareValue, reflect.Value{}) 358 return true 359 } 360 } 361 return false 362 } 363 364 // Deprecated: 清空集合中的元素 365 // collection: 指针类型的map或slice 366 func Clear(collection interface{}) bool { 367 if collection == nil { 368 return false 369 } 370 collectionValue := reflect.ValueOf(collection) 371 cKind := collectionValue.Kind() 372 if cKind != reflect.Ptr { 373 xlog.Panic("xcollect.Clear: collection must be pointer, this kind is", cKind) 374 return false 375 } 376 switch collectionValue.Elem().Kind() { 377 case reflect.Slice, reflect.Array: 378 nslice := reflect.MakeSlice(collectionValue.Type().Elem(), 0, 0) 379 collectionValue.Elem().Set(nslice) 380 return true 381 case reflect.Map: 382 nmap := reflect.MakeMap(collectionValue.Type().Elem()) 383 collectionValue.Elem().Set(nmap) 384 return true 385 } 386 return false 387 }