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  }