github.com/PandaGoAdmin/utils@v0.0.0-20211208134815-d5461603a00f/array.go (about)

     1  package kgo
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"math"
     7  	"math/rand"
     8  	"reflect"
     9  	"sort"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  )
    14  
    15  // ArrayKeys 返回数组(切片/字典/结构体)中所有的键名;如果是结构体,只返回公开的字段.
    16  func (ka *LkkArray) ArrayKeys(arr interface{}) []interface{} {
    17  	val := reflect.ValueOf(arr)
    18  	typ := val.Kind()
    19  	if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Struct && typ != reflect.Map {
    20  		panic("[ArrayKeys]`arr type must be array|slice|map|struct; but : " + typ.String())
    21  	}
    22  
    23  	var res []interface{}
    24  	switch typ {
    25  	case reflect.Array, reflect.Slice:
    26  		for i := 0; i < val.Len(); i++ {
    27  			res = append(res, i)
    28  		}
    29  	case reflect.Map:
    30  		for _, k := range val.MapKeys() {
    31  			res = append(res, k)
    32  		}
    33  	case reflect.Struct:
    34  		var t = val.Type()
    35  		for i := 0; i < t.NumField(); i++ {
    36  			field := t.Field(i)
    37  			// 不能访问未导出的字段
    38  			if field.PkgPath != "" {
    39  				continue
    40  			}
    41  			res = append(res, field.Name)
    42  		}
    43  	}
    44  
    45  	return res
    46  }
    47  
    48  // ArrayValues 返回arr(数组/切片/字典/结构体)中所有的值;如果是结构体,只返回公开字段的值.
    49  // filterZero 是否过滤零值元素(nil,false,0,"",[]),true时排除零值元素,false时保留零值元素.
    50  func (ka *LkkArray) ArrayValues(arr interface{}, filterZero bool) []interface{} {
    51  	return arrayValues(arr, filterZero)
    52  }
    53  
    54  // ArrayChunk 将一个数组/切片分割成多个,size为每个子数组的长度.
    55  func (ka *LkkArray) ArrayChunk(arr interface{}, size int) [][]interface{} {
    56  	if size < 1 {
    57  		panic("[ArrayChunk]`size cannot be less than 1")
    58  	}
    59  
    60  	val := reflect.ValueOf(arr)
    61  	switch val.Kind() {
    62  	case reflect.Array, reflect.Slice:
    63  		length := val.Len()
    64  		if length == 0 {
    65  			return nil
    66  		}
    67  
    68  		chunkNum := int(math.Ceil(float64(length) / float64(size)))
    69  		var res [][]interface{}
    70  		var item []interface{}
    71  		var start int
    72  		for i, end := 0, 0; chunkNum > 0; chunkNum-- {
    73  			end = (i + 1) * size
    74  			if end > length {
    75  				end = length
    76  			}
    77  
    78  			item = nil
    79  			start = i * size
    80  			for ; start < end; start++ {
    81  				item = append(item, val.Index(start).Interface())
    82  			}
    83  			if item != nil {
    84  				res = append(res, item)
    85  			}
    86  
    87  			i++
    88  		}
    89  
    90  		return res
    91  	default:
    92  		panic("[ArrayChunk]`arr type must be array|slice; but : " + val.Kind().String())
    93  	}
    94  }
    95  
    96  // ArrayColumn 返回数组(切片/字典/结构体)中元素指定的一列.
    97  // arr的元素必须是字典;
    98  // columnKey为元素的字段名;
    99  // 该方法效率较低.
   100  func (ka *LkkArray) ArrayColumn(arr interface{}, columnKey string) []interface{} {
   101  	val := reflect.ValueOf(arr)
   102  	var res []interface{}
   103  	var err error
   104  	var item interface{}
   105  	switch val.Kind() {
   106  	case reflect.Array, reflect.Slice:
   107  		for i := 0; i < val.Len(); i++ {
   108  			item, err = GetFieldValue(val.Index(i).Interface(), columnKey)
   109  			if item != nil && err == nil {
   110  				res = append(res, item)
   111  			}
   112  		}
   113  	case reflect.Map:
   114  		for _, k := range val.MapKeys() {
   115  			item, err = GetFieldValue(val.MapIndex(k).Interface(), columnKey)
   116  			if item != nil && err == nil {
   117  				res = append(res, item)
   118  			}
   119  		}
   120  	case reflect.Struct:
   121  		for i := 0; i < val.NumField(); i++ {
   122  			item, err = GetFieldValue(reflect2Itf(val.Field(i)), columnKey)
   123  			if item != nil && err == nil {
   124  				res = append(res, item)
   125  			}
   126  		}
   127  	default:
   128  		panic("[ArrayColumn]`arr type must be array|slice|map|struct; but : " + val.Kind().String())
   129  	}
   130  
   131  	return res
   132  }
   133  
   134  // SlicePush 将一个或多个元素压入切片的末尾(入栈),返回处理之后切片的元素个数.
   135  func (ka *LkkArray) SlicePush(s *[]interface{}, elements ...interface{}) int {
   136  	*s = append(*s, elements...)
   137  	return len(*s)
   138  }
   139  
   140  // SlicePop 弹出切片最后一个元素(出栈),并返回该元素.
   141  func (ka *LkkArray) SlicePop(s *[]interface{}) interface{} {
   142  	if len(*s) == 0 {
   143  		return nil
   144  	}
   145  	ep := len(*s) - 1
   146  	e := (*s)[ep]
   147  	*s = (*s)[:ep]
   148  	return e
   149  }
   150  
   151  // SliceUnshift 在切片开头插入一个或多个元素,返回处理之后切片的元素个数.
   152  func (ka *LkkArray) SliceUnshift(s *[]interface{}, elements ...interface{}) int {
   153  	*s = append(elements, *s...)
   154  	return len(*s)
   155  }
   156  
   157  // SliceShift 将切片开头的元素移出,并返回该元素.
   158  func (ka *LkkArray) SliceShift(s *[]interface{}) interface{} {
   159  	if len(*s) == 0 {
   160  		return nil
   161  	}
   162  	e := (*s)[0]
   163  	*s = (*s)[1:]
   164  	return e
   165  }
   166  
   167  // ArrayKeyExists 检查arr(数组/切片/字典/结构体)里是否有key指定的键名(索引/字段).
   168  func (ka *LkkArray) ArrayKeyExists(key interface{}, arr interface{}) bool {
   169  	val := reflect.ValueOf(arr)
   170  	typ := val.Kind()
   171  
   172  	if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Struct && typ != reflect.Map {
   173  		panic("[ArrayKeyExists]`arr type must be array|slice|map|struct; but : " + typ.String())
   174  	}
   175  
   176  	if key == nil {
   177  		return false
   178  	}
   179  
   180  	switch typ {
   181  	case reflect.Array, reflect.Slice:
   182  		var keyInt int
   183  		var keyIsInt, ok bool
   184  		if keyInt, ok = key.(int); ok {
   185  			keyIsInt = true
   186  		}
   187  
   188  		length := val.Len()
   189  		if keyIsInt && length > 0 && keyInt >= 0 && keyInt < length {
   190  			return true
   191  		}
   192  	case reflect.Map:
   193  		for _, k := range val.MapKeys() {
   194  			if fmt.Sprintf("%s", key) == fmt.Sprintf("%s", k) || reflect.DeepEqual(key, k) {
   195  				return true
   196  			}
   197  		}
   198  	case reflect.Struct:
   199  		field := val.FieldByName(fmt.Sprintf("%s", key))
   200  		if field.IsValid() {
   201  			return true
   202  		}
   203  	}
   204  
   205  	return false
   206  }
   207  
   208  // ArrayReverse 返回单元顺序相反的数组(仅限数组和切片).
   209  func (ka *LkkArray) ArrayReverse(arr interface{}) []interface{} {
   210  	val := reflect.ValueOf(arr)
   211  	switch val.Kind() {
   212  	case reflect.Array, reflect.Slice:
   213  		length := val.Len()
   214  		res := make([]interface{}, length)
   215  		i, j := 0, length-1
   216  		for ; i < j; i, j = i+1, j-1 {
   217  			res[i], res[j] = val.Index(j).Interface(), val.Index(i).Interface()
   218  		}
   219  		if length > 0 && res[j] == nil {
   220  			res[j] = val.Index(j).Interface()
   221  		}
   222  
   223  		return res
   224  	default:
   225  		panic("[ArrayReverse]`arr type must be array|slice; but : " + val.Kind().String())
   226  	}
   227  }
   228  
   229  // Implode 用delimiter将数组(数组/切片/字典/结构体)的值连接为一个字符串.
   230  func (ka *LkkArray) Implode(delimiter string, arr interface{}) string {
   231  	val := reflect.ValueOf(arr)
   232  	var buf bytes.Buffer
   233  	var length, j int
   234  	switch val.Kind() {
   235  	case reflect.Array, reflect.Slice:
   236  		length = val.Len()
   237  		if length == 0 {
   238  			return ""
   239  		}
   240  		j = length
   241  		for i := 0; i < length; i++ {
   242  			buf.WriteString(toStr(val.Index(i).Interface()))
   243  			if j--; j > 0 {
   244  				buf.WriteString(delimiter)
   245  			}
   246  		}
   247  	case reflect.Map:
   248  		length = len(val.MapKeys())
   249  		if length == 0 {
   250  			return ""
   251  		}
   252  		for _, k := range val.MapKeys() {
   253  			buf.WriteString(toStr(val.MapIndex(k).Interface()))
   254  			if length--; length > 0 {
   255  				buf.WriteString(delimiter)
   256  			}
   257  		}
   258  	case reflect.Struct:
   259  		length = val.NumField()
   260  		if length == 0 {
   261  			return ""
   262  		}
   263  		j = length
   264  		for i := 0; i < length; i++ {
   265  			j--
   266  			if val.Field(i).CanInterface() {
   267  				buf.WriteString(toStr(val.Field(i).Interface()))
   268  				if j > 0 {
   269  					buf.WriteString(delimiter)
   270  				}
   271  			}
   272  		}
   273  	default:
   274  		panic("[Implode]`arr type must be array|slice|map|struct; but : " + val.Kind().String())
   275  	}
   276  
   277  	return buf.String()
   278  }
   279  
   280  // JoinStrings 使用分隔符delimiter连接字符串切片strs.效率比Implode高.
   281  func (ka *LkkArray) JoinStrings(delimiter string, strs []string) (res string) {
   282  	length := len(strs)
   283  	if length == 0 {
   284  		return
   285  	}
   286  
   287  	var sb strings.Builder
   288  	for _, str := range strs {
   289  		sb.WriteString(str)
   290  		if length--; length > 0 {
   291  			sb.WriteString(delimiter)
   292  		}
   293  	}
   294  	res = sb.String()
   295  
   296  	return
   297  }
   298  
   299  // JoinInts 使用分隔符delimiter连接整数切片.
   300  func (ka *LkkArray) JoinInts(delimiter string, ints []int) (res string) {
   301  	length := len(ints)
   302  	if length == 0 {
   303  		return
   304  	}
   305  
   306  	var sb strings.Builder
   307  	for _, num := range ints {
   308  		sb.WriteString(strconv.Itoa(num))
   309  		if length--; length > 0 {
   310  			sb.WriteString(delimiter)
   311  		}
   312  	}
   313  	res = sb.String()
   314  
   315  	return
   316  }
   317  
   318  // UniqueInts 移除整数切片中的重复值.
   319  func (ka *LkkArray) UniqueInts(ints []int) (res []int) {
   320  	sort.Ints(ints)
   321  	var last int
   322  	for i, num := range ints {
   323  		if i == 0 || num != last {
   324  			res = append(res, num)
   325  		}
   326  		last = num
   327  	}
   328  	return
   329  }
   330  
   331  // Unique64Ints 移除64位整数切片中的重复值.
   332  func (ka *LkkArray) Unique64Ints(ints []int64) (res []int64) {
   333  	seen := make(map[int64]bool)
   334  	for _, num := range ints {
   335  		if _, ok := seen[num]; !ok {
   336  			seen[num] = true
   337  			res = append(res, num)
   338  		}
   339  	}
   340  	return
   341  }
   342  
   343  // UniqueStrings 移除字符串切片中的重复值.
   344  func (ka *LkkArray) UniqueStrings(strs []string) (res []string) {
   345  	sort.Strings(strs)
   346  	var last string
   347  	for _, str := range strs {
   348  		if str != last {
   349  			res = append(res, str)
   350  		}
   351  		last = str
   352  	}
   353  
   354  	return
   355  }
   356  
   357  // ArrayDiff 计算数组(数组/切片/字典)的交集,返回在 arr1 中但不在 arr2 里的元素,注意会同时返回键.
   358  // compareType为两个数组的比较方式,枚举类型,有:
   359  // COMPARE_ONLY_VALUE 根据元素值比较, 返回在 arr1 中但是不在arr2 里的值;
   360  // COMPARE_ONLY_KEY 根据 arr1 中的键名和 arr2 进行比较,返回不同键名的项;
   361  // COMPARE_BOTH_KEYVALUE 同时比较键和值.
   362  func (ka *LkkArray) ArrayDiff(arr1, arr2 interface{}, compareType LkkArrCompareType) map[interface{}]interface{} {
   363  	valA := reflect.ValueOf(arr1)
   364  	valB := reflect.ValueOf(arr2)
   365  	typA := valA.Kind()
   366  	typB := valB.Kind()
   367  
   368  	if (typA != reflect.Array && typA != reflect.Slice && typA != reflect.Map) || (typB != reflect.Array && typB != reflect.Slice && typB != reflect.Map) {
   369  		panic("[ArrayDiff]`arr1,arr2 type must be array|slice|map; but : " + typA.String() + "/" + typB.String())
   370  	}
   371  
   372  	lenA := valA.Len()
   373  	lenB := valB.Len()
   374  	if lenA == 0 {
   375  		return nil
   376  	}
   377  
   378  	resMap := make(map[interface{}]interface{})
   379  	var iteA interface{}
   380  	var chkKey bool
   381  	var chkVal bool
   382  	var chkRes bool
   383  
   384  	if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Array || typB == reflect.Slice) {
   385  		//两者都是数组/切片
   386  		for i := 0; i < lenA; i++ {
   387  			iteA = valA.Index(i).Interface()
   388  			chkRes = true
   389  
   390  			if compareType == COMPARE_BOTH_KEYVALUE {
   391  				if i < lenB {
   392  					chkRes = !reflect.DeepEqual(iteA, valB.Index(i).Interface())
   393  				}
   394  			} else if compareType == COMPARE_ONLY_KEY {
   395  				chkRes = lenB > 0 && i >= lenB
   396  			} else if compareType == COMPARE_ONLY_VALUE {
   397  				for j := 0; j < lenB; j++ {
   398  					chkRes = !reflect.DeepEqual(iteA, valB.Index(j).Interface())
   399  					if !chkRes {
   400  						break
   401  					}
   402  				}
   403  			}
   404  
   405  			if chkRes {
   406  				resMap[i] = iteA
   407  			}
   408  		}
   409  	} else if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Map) {
   410  		//A是数组/切片,B是字典
   411  		for i := 0; i < lenA; i++ {
   412  			iteA = valA.Index(i).Interface()
   413  			chkRes = true
   414  
   415  			for _, k := range valB.MapKeys() {
   416  				chkKey = isInt(k.Interface()) && toInt(k.Interface()) == i
   417  				chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k).Interface())
   418  
   419  				if compareType == COMPARE_ONLY_KEY && chkKey {
   420  					chkRes = false
   421  					break
   422  				} else if compareType == COMPARE_ONLY_VALUE && chkVal {
   423  					chkRes = false
   424  					break
   425  				} else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey && chkVal) {
   426  					chkRes = false
   427  					break
   428  				}
   429  			}
   430  
   431  			if chkRes {
   432  				resMap[i] = iteA
   433  			}
   434  		}
   435  	} else if (typA == reflect.Map) && (typB == reflect.Array || typB == reflect.Slice) {
   436  		//A是字典,B是数组/切片
   437  		var kv int
   438  		for _, k := range valA.MapKeys() {
   439  			iteA = valA.MapIndex(k).Interface()
   440  			chkRes = true
   441  
   442  			if isInt(k.Interface()) {
   443  				kv = toInt(k.Interface())
   444  			} else {
   445  				kv = -1
   446  			}
   447  
   448  			if compareType == COMPARE_BOTH_KEYVALUE {
   449  				if kv >= 0 && kv < lenB {
   450  					chkRes = !reflect.DeepEqual(iteA, valB.Index(kv).Interface())
   451  				}
   452  			} else if compareType == COMPARE_ONLY_KEY {
   453  				chkRes = (kv < 0 || kv >= lenB)
   454  			} else if compareType == COMPARE_ONLY_VALUE {
   455  				for i := 0; i < lenB; i++ {
   456  					chkRes = !reflect.DeepEqual(iteA, valB.Index(i).Interface())
   457  					if !chkRes {
   458  						break
   459  					}
   460  				}
   461  			}
   462  
   463  			if chkRes {
   464  				resMap[k.Interface()] = iteA
   465  			}
   466  		}
   467  	} else if (typA == reflect.Map) && (typB == reflect.Map) {
   468  		//两者都是字典
   469  		var kv string
   470  		for _, k := range valA.MapKeys() {
   471  			iteA = valA.MapIndex(k).Interface()
   472  			chkRes = true
   473  			kv = toStr(k.Interface())
   474  
   475  			for _, k2 := range valB.MapKeys() {
   476  				chkKey = kv == toStr(k2.Interface())
   477  				chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k2).Interface())
   478  
   479  				if compareType == COMPARE_ONLY_KEY && chkKey {
   480  					chkRes = false
   481  					break
   482  				} else if compareType == COMPARE_ONLY_VALUE && chkVal {
   483  					chkRes = false
   484  					break
   485  				} else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey || chkVal) {
   486  					chkRes = false
   487  					break
   488  				}
   489  			}
   490  
   491  			if chkRes {
   492  				resMap[k.Interface()] = iteA
   493  			}
   494  		}
   495  	}
   496  
   497  	return resMap
   498  }
   499  
   500  // ArrayIntersect 计算数组(数组/切片/字典)的交集,返回在 arr1 中且在 arr2 里的元素,注意会同时返回键.
   501  // compareType为两个数组的比较方式,枚举类型,有:
   502  // COMPARE_ONLY_VALUE 根据元素值比较, 返回在 arr1 中且在arr2 里的值;
   503  // COMPARE_ONLY_KEY 根据 arr1 中的键名和 arr2 进行比较,返回相同键名的项;
   504  // COMPARE_BOTH_KEYVALUE 同时比较键和值.
   505  func (ka *LkkArray) ArrayIntersect(arr1, arr2 interface{}, compareType LkkArrCompareType) map[interface{}]interface{} {
   506  	valA := reflect.ValueOf(arr1)
   507  	valB := reflect.ValueOf(arr2)
   508  	typA := valA.Kind()
   509  	typB := valB.Kind()
   510  
   511  	if (typA != reflect.Array && typA != reflect.Slice && typA != reflect.Map) || (typB != reflect.Array && typB != reflect.Slice && typB != reflect.Map) {
   512  		panic("[ArrayIntersect]`arr1,arr2 type must be array|slice|map; but : " + typA.String() + "/" + typB.String())
   513  	}
   514  
   515  	lenA := valA.Len()
   516  	lenB := valB.Len()
   517  	if lenA == 0 || lenB == 0 {
   518  		return nil
   519  	}
   520  
   521  	resMap := make(map[interface{}]interface{})
   522  	var iteA interface{}
   523  	var chkKey bool
   524  	var chkVal bool
   525  	var chkRes bool
   526  
   527  	if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Array || typB == reflect.Slice) {
   528  		//两者都是数组/切片
   529  		for i := 0; i < lenA; i++ {
   530  			iteA = valA.Index(i).Interface()
   531  			chkRes = false
   532  
   533  			if compareType == COMPARE_BOTH_KEYVALUE {
   534  				if i < lenB {
   535  					chkRes = reflect.DeepEqual(iteA, valB.Index(i).Interface())
   536  				}
   537  			} else if compareType == COMPARE_ONLY_KEY {
   538  				chkRes = i < lenB
   539  			} else if compareType == COMPARE_ONLY_VALUE {
   540  				for j := 0; j < lenB; j++ {
   541  					chkRes = reflect.DeepEqual(iteA, valB.Index(j).Interface())
   542  					if chkRes {
   543  						break
   544  					}
   545  				}
   546  			}
   547  
   548  			if chkRes {
   549  				resMap[i] = iteA
   550  			}
   551  		}
   552  	} else if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Map) {
   553  		//A是数组/切片,B是字典
   554  		for i := 0; i < lenA; i++ {
   555  			iteA = valA.Index(i).Interface()
   556  			chkRes = false
   557  
   558  			for _, k := range valB.MapKeys() {
   559  				chkKey = isInt(k.Interface()) && toInt(k.Interface()) == i
   560  				chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k).Interface())
   561  
   562  				if compareType == COMPARE_ONLY_KEY && chkKey {
   563  					chkRes = true
   564  					break
   565  				} else if compareType == COMPARE_ONLY_VALUE && chkVal {
   566  					chkRes = true
   567  					break
   568  				} else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey && chkVal) {
   569  					chkRes = true
   570  					break
   571  				}
   572  			}
   573  
   574  			if chkRes {
   575  				resMap[i] = iteA
   576  			}
   577  		}
   578  	} else if (typA == reflect.Map) && (typB == reflect.Array || typB == reflect.Slice) {
   579  		//A是字典,B是数组/切片
   580  		var kv int
   581  		for _, k := range valA.MapKeys() {
   582  			iteA = valA.MapIndex(k).Interface()
   583  			chkRes = false
   584  
   585  			if isInt(k.Interface()) {
   586  				kv = toInt(k.Interface())
   587  			} else {
   588  				kv = -1
   589  			}
   590  
   591  			if compareType == COMPARE_BOTH_KEYVALUE {
   592  				if kv >= 0 && kv < lenB {
   593  					chkRes = reflect.DeepEqual(iteA, valB.Index(kv).Interface())
   594  				}
   595  			} else if compareType == COMPARE_ONLY_KEY {
   596  				chkRes = kv >= 0 && kv < lenB
   597  			} else if compareType == COMPARE_ONLY_VALUE {
   598  				for i := 0; i < lenB; i++ {
   599  					chkRes = reflect.DeepEqual(iteA, valB.Index(i).Interface())
   600  					if chkRes {
   601  						break
   602  					}
   603  				}
   604  			}
   605  
   606  			if chkRes {
   607  				resMap[k.Interface()] = iteA
   608  			}
   609  		}
   610  	} else if (typA == reflect.Map) && (typB == reflect.Map) {
   611  		//两者都是字典
   612  		var kv string
   613  		for _, k := range valA.MapKeys() {
   614  			iteA = valA.MapIndex(k).Interface()
   615  			chkRes = false
   616  			kv = toStr(k.Interface())
   617  
   618  			for _, k2 := range valB.MapKeys() {
   619  				chkKey = kv == toStr(k2.Interface())
   620  				chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k2).Interface())
   621  
   622  				if compareType == COMPARE_ONLY_KEY && chkKey {
   623  					chkRes = true
   624  					break
   625  				} else if compareType == COMPARE_ONLY_VALUE && chkVal {
   626  					chkRes = true
   627  					break
   628  				} else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey && chkVal) {
   629  					chkRes = true
   630  					break
   631  				}
   632  			}
   633  
   634  			if chkRes {
   635  				resMap[k.Interface()] = iteA
   636  			}
   637  		}
   638  	}
   639  
   640  	return resMap
   641  }
   642  
   643  // ArrayUnique 移除数组(切片/字典)中重复的值,返回字典,保留键名.
   644  func (ka *LkkArray) ArrayUnique(arr interface{}) map[interface{}]interface{} {
   645  	var item interface{}
   646  	var str, key string
   647  	val := reflect.ValueOf(arr)
   648  	chkMp := make(map[string]interface{})
   649  	res := make(map[interface{}]interface{})
   650  	switch val.Kind() {
   651  	case reflect.Array, reflect.Slice:
   652  		for i := 0; i < val.Len(); i++ {
   653  			item = val.Index(i).Interface()
   654  			str = fmt.Sprintf("%+v", item)
   655  			key = string(md5Byte([]byte(str), 32))
   656  			if _, ok := chkMp[key]; !ok {
   657  				chkMp[key] = true
   658  				res[i] = item
   659  			}
   660  		}
   661  	case reflect.Map:
   662  		for _, k := range val.MapKeys() {
   663  			item = val.MapIndex(k).Interface()
   664  			str = fmt.Sprintf("%+v", item)
   665  			key = string(md5Byte([]byte(str), 32))
   666  			if _, ok := chkMp[key]; !ok {
   667  				chkMp[key] = true
   668  				res[reflect2Itf(k)] = item
   669  			}
   670  		}
   671  	default:
   672  		panic("[ArrayUnique]`arr type must be array|slice|map; but : " + val.Kind().String())
   673  	}
   674  
   675  	return res
   676  }
   677  
   678  // ArraySearchItem 从数组(切片/字典)中搜索对应元素(单个).
   679  // arr为要查找的数组,元素必须为字典/结构体;condition为条件字典.
   680  func (ka *LkkArray) ArraySearchItem(arr interface{}, condition map[string]interface{}) (res interface{}) {
   681  	val := reflect.ValueOf(arr)
   682  	typ := val.Kind()
   683  	if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Map {
   684  		panic("[ArraySearchItem]`arr type must be array|slice|map; but : " + typ.String())
   685  	}
   686  
   687  	// 条件为空
   688  	if len(condition) == 0 {
   689  		return
   690  	}
   691  
   692  	switch typ {
   693  	case reflect.Array, reflect.Slice:
   694  		for i := 0; i < val.Len(); i++ {
   695  			res = compareConditionMap(condition, val.Index(i).Interface())
   696  			if res != nil {
   697  				return
   698  			}
   699  		}
   700  	case reflect.Map:
   701  		for _, k := range val.MapKeys() {
   702  			res = compareConditionMap(condition, val.MapIndex(k).Interface())
   703  			if res != nil {
   704  				return
   705  			}
   706  		}
   707  	}
   708  
   709  	return
   710  }
   711  
   712  // ArraySearchMutil 从数组(切片/字典)中搜索对应元素(多个).
   713  // arr为要查找的数组,元素必须为字典/结构体;condition为条件字典.
   714  func (ka *LkkArray) ArraySearchMutil(arr interface{}, condition map[string]interface{}) (res []interface{}) {
   715  	val := reflect.ValueOf(arr)
   716  	typ := val.Kind()
   717  	if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Map {
   718  		panic("[ArraySearchMutil]`arr type must be array|slice|map; but : " + typ.String())
   719  	}
   720  
   721  	// 条件为空
   722  	if len(condition) == 0 {
   723  		return
   724  	}
   725  
   726  	var item interface{}
   727  	switch typ {
   728  	case reflect.Array, reflect.Slice:
   729  		for i := 0; i < val.Len(); i++ {
   730  			item = compareConditionMap(condition, val.Index(i).Interface())
   731  			if item != nil {
   732  				res = append(res, item)
   733  			}
   734  		}
   735  	case reflect.Map:
   736  		for _, k := range val.MapKeys() {
   737  			item = compareConditionMap(condition, val.MapIndex(k).Interface())
   738  			if item != nil {
   739  				res = append(res, item)
   740  			}
   741  		}
   742  	}
   743  
   744  	return
   745  }
   746  
   747  // ArrayShuffle 打乱数组/切片排序.
   748  func (ka *LkkArray) ArrayShuffle(arr interface{}) []interface{} {
   749  	val := reflect.ValueOf(arr)
   750  	typ := val.Kind()
   751  	if typ != reflect.Array && typ != reflect.Slice {
   752  		panic("[ArrayShuffle]`arr type must be array|slice; but : " + typ.String())
   753  	}
   754  
   755  	num := val.Len()
   756  	res := make([]interface{}, num)
   757  
   758  	for i := 0; i < num; i++ {
   759  		res[i] = val.Index(i).Interface()
   760  	}
   761  
   762  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   763  	r.Shuffle(num, func(i, j int) {
   764  		res[i], res[j] = res[j], res[i]
   765  	})
   766  
   767  	return res
   768  }
   769  
   770  // IsEqualArray 两个数组/切片是否相同(不管元素顺序),且不会检查元素类型;
   771  // arr1, arr2 是要比较的数组/切片.
   772  func (ka *LkkArray) IsEqualArray(arr1, arr2 interface{}) bool {
   773  	valA := reflect.ValueOf(arr1)
   774  	valB := reflect.ValueOf(arr2)
   775  	typA := valA.Kind()
   776  	typB := valB.Kind()
   777  
   778  	if (typA != reflect.Array && typA != reflect.Slice) || (typB != reflect.Array && typB != reflect.Slice) {
   779  		panic("[IsEqualArray]`arr1,arr2 type must be array|slice; but : " + typA.String() + "/" + typB.String())
   780  	}
   781  
   782  	length := valA.Len()
   783  	if length != valB.Len() {
   784  		return false
   785  	}
   786  
   787  	var itmAStr, itmBstr string
   788  	var format string = "%#v"
   789  	expectedMap := make(map[string]bool)
   790  	actualMap := make(map[string]bool)
   791  	for i := 0; i < length; i++ {
   792  		itmAStr = fmt.Sprintf(format, valA.Index(i).Interface())
   793  		itmBstr = fmt.Sprintf(format, valB.Index(i).Interface())
   794  		expectedMap[itmAStr] = true
   795  		actualMap[itmBstr] = true
   796  	}
   797  
   798  	return reflect.DeepEqual(expectedMap, actualMap)
   799  }
   800  
   801  // IsEqualMap 两个字典是否相同(不管键顺序),且不会严格检查元素类型;
   802  // arr1, arr2 是要比较的字典.
   803  func (ka *LkkArray) IsEqualMap(arr1, arr2 interface{}) bool {
   804  	valA := reflect.ValueOf(arr1)
   805  	valB := reflect.ValueOf(arr2)
   806  	typA := valA.Kind()
   807  	typB := valB.Kind()
   808  
   809  	if typA != reflect.Map || typB != reflect.Map {
   810  		panic("[IsEqualMap]`arr1,arr2 type must be array|slice; but : " + typA.String() + "/" + typB.String())
   811  	}
   812  
   813  	length := valA.Len()
   814  	if length != valB.Len() {
   815  		return false
   816  	}
   817  
   818  	var key string
   819  	expectedMap := make(map[string]interface{})
   820  	actualMap := make(map[string]interface{})
   821  
   822  	for _, k := range valA.MapKeys() {
   823  		key = fmt.Sprintf("%v", k)
   824  		expectedMap[key] = fmt.Sprintf("%#v", valA.MapIndex(k).Interface())
   825  	}
   826  	for _, k := range valB.MapKeys() {
   827  		key = fmt.Sprintf("%v", k)
   828  		actualMap[key] = fmt.Sprintf("%#v", valB.MapIndex(k).Interface())
   829  	}
   830  
   831  	return reflect.DeepEqual(expectedMap, actualMap)
   832  }
   833  
   834  // Length 获取数组/切片的长度;结果为-1表示变量不是数组或切片.
   835  func (ka *LkkArray) Length(val interface{}) int {
   836  	return lenArrayOrSlice(val, 3)
   837  }
   838  
   839  // IsArray 变量是否数组.
   840  func (ka *LkkArray) IsArray(val interface{}) bool {
   841  	l := lenArrayOrSlice(val, 1)
   842  	return l >= 0
   843  }
   844  
   845  // IsSlice 变量是否切片.
   846  func (ka *LkkArray) IsSlice(val interface{}) bool {
   847  	l := lenArrayOrSlice(val, 2)
   848  	return l >= 0
   849  }
   850  
   851  // IsArrayOrSlice 变量是否数组或切片.
   852  func (ka *LkkArray) IsArrayOrSlice(val interface{}) bool {
   853  	l := lenArrayOrSlice(val, 3)
   854  	return l >= 0
   855  }
   856  
   857  // IsMap 变量是否字典.
   858  func (ka *LkkArray) IsMap(val interface{}) bool {
   859  	return isMap(val)
   860  }
   861  
   862  // IsStruct 变量是否结构体.
   863  func (ka *LkkArray) IsStruct(val interface{}) bool {
   864  	return isStruct(val)
   865  }
   866  
   867  // DeleteSliceItems 删除数组/切片的元素,返回一个新切片.
   868  // ids为多个元素的索引(0~len(val)-1);
   869  // del为删除元素的数量.
   870  func (ka *LkkArray) DeleteSliceItems(val interface{}, ids ...int) (res []interface{}, del int) {
   871  	sl := reflect.ValueOf(val)
   872  	styp := sl.Kind()
   873  
   874  	if styp != reflect.Array && styp != reflect.Slice {
   875  		panic("[DeleteSliceItems]`val type must be array|slice")
   876  	}
   877  
   878  	slen := sl.Len()
   879  	if slen == 0 {
   880  		return
   881  	}
   882  
   883  	var item interface{}
   884  	var chk bool
   885  	for i := 0; i < slen; i++ {
   886  		item = sl.Index(i).Interface()
   887  		chk = true
   888  
   889  		for _, v := range ids {
   890  			if i == v {
   891  				del++
   892  				chk = false
   893  				break
   894  			}
   895  		}
   896  
   897  		if chk {
   898  			res = append(res, item)
   899  		}
   900  	}
   901  
   902  	return
   903  }
   904  
   905  // InArray 元素needle是否在数组haystack(切片/字典)内.
   906  func (ka *LkkArray) InArray(needle interface{}, haystack interface{}) bool {
   907  	val := reflect.ValueOf(haystack)
   908  	switch val.Kind() {
   909  	case reflect.Array, reflect.Slice:
   910  		for i := 0; i < val.Len(); i++ {
   911  			if reflect.DeepEqual(needle, val.Index(i).Interface()) {
   912  				return true
   913  			}
   914  		}
   915  	case reflect.Map:
   916  		for _, k := range val.MapKeys() {
   917  			if reflect.DeepEqual(needle, val.MapIndex(k).Interface()) {
   918  				return true
   919  			}
   920  		}
   921  	default:
   922  		panic("[InArray]`haystack type must be array|slice|map")
   923  	}
   924  
   925  	return false
   926  }
   927  
   928  // InIntSlice 是否在整型切片内.
   929  func (ka *LkkArray) InIntSlice(i int, list []int) bool {
   930  	for _, item := range list {
   931  		if item == i {
   932  			return true
   933  		}
   934  	}
   935  	return false
   936  }
   937  
   938  // InInt64Slice 是否在64位整型切片内.
   939  func (ka *LkkArray) InInt64Slice(i int64, list []int64) bool {
   940  	for _, item := range list {
   941  		if item == i {
   942  			return true
   943  		}
   944  	}
   945  	return false
   946  }
   947  
   948  // InStringSlice 是否在字符串切片内.
   949  func (ka *LkkArray) InStringSlice(str string, list []string) bool {
   950  	for _, item := range list {
   951  		if item == str {
   952  			return true
   953  		}
   954  	}
   955  	return false
   956  }
   957  
   958  // SliceFill 用给定的值val填充切片,num为插入元素的数量.
   959  func (ka *LkkArray) SliceFill(val interface{}, num int) []interface{} {
   960  	if num <= 0 {
   961  		return nil
   962  	}
   963  
   964  	var res = make([]interface{}, num)
   965  	for i := 0; i < num; i++ {
   966  		res[i] = val
   967  	}
   968  
   969  	return res
   970  }
   971  
   972  // ArrayFlip 交换数组(切片/字典)中的键和值.
   973  func (ka *LkkArray) ArrayFlip(arr interface{}) map[interface{}]interface{} {
   974  	res := make(map[interface{}]interface{})
   975  	val := reflect.ValueOf(arr)
   976  	var key interface{}
   977  	switch val.Kind() {
   978  	case reflect.Array, reflect.Slice:
   979  		for i := 0; i < val.Len(); i++ {
   980  			key = val.Index(i).Interface()
   981  			if key != nil && fmt.Sprintf("%v", key) != "" {
   982  				res[key] = i
   983  			}
   984  		}
   985  	case reflect.Map:
   986  		for _, k := range val.MapKeys() {
   987  			key = val.MapIndex(k).Interface()
   988  			if key != nil && fmt.Sprintf("%v", key) != "" {
   989  				res[key] = k
   990  			}
   991  		}
   992  	default:
   993  		panic("[ArrayFlip]`arr type must be array|slice|map")
   994  	}
   995  
   996  	return res
   997  }
   998  
   999  // MergeSlice 合并一个或多个数组/切片.
  1000  // filterZero 是否过滤零值元素(nil,false,0,'',[]),true时排除零值元素,false时保留零值元素.
  1001  // ss是元素为数组/切片的切片.
  1002  func (ka *LkkArray) MergeSlice(filterZero bool, ss ...interface{}) []interface{} {
  1003  	var res []interface{}
  1004  	switch len(ss) {
  1005  	case 0:
  1006  		break
  1007  	default:
  1008  		n := 0
  1009  		for i, v := range ss {
  1010  			chkLen := lenArrayOrSlice(v, 3)
  1011  			if chkLen == -1 {
  1012  				msg := fmt.Sprintf("[MergeSlice]`ss type must be array|slice, but [%d]th item not is.", i)
  1013  				panic(msg)
  1014  			} else {
  1015  				n += chkLen
  1016  			}
  1017  		}
  1018  		res = make([]interface{}, 0, n)
  1019  		var item interface{}
  1020  		for _, v := range ss {
  1021  			val := reflect.ValueOf(v)
  1022  			switch val.Kind() {
  1023  			case reflect.Array, reflect.Slice:
  1024  				for i := 0; i < val.Len(); i++ {
  1025  					item = val.Index(i).Interface()
  1026  					if !filterZero || (filterZero && !val.Index(i).IsZero()) {
  1027  						res = append(res, item)
  1028  					}
  1029  				}
  1030  			}
  1031  		}
  1032  	}
  1033  
  1034  	return res
  1035  }
  1036  
  1037  // MergeMap 合并字典,相同的键名时,后面的值将覆盖前一个值.
  1038  // ss是元素为字典的切片.
  1039  func (ka *LkkArray) MergeMap(ss ...interface{}) map[interface{}]interface{} {
  1040  	res := make(map[interface{}]interface{})
  1041  	switch len(ss) {
  1042  	case 0:
  1043  		break
  1044  	default:
  1045  		for i, v := range ss {
  1046  			val := reflect.ValueOf(v)
  1047  			switch val.Kind() {
  1048  			case reflect.Map:
  1049  				for _, k := range val.MapKeys() {
  1050  					res[reflect2Itf(k)] = val.MapIndex(k).Interface()
  1051  				}
  1052  			default:
  1053  				panic(fmt.Sprintf("[MergeMap]`ss type must be map, but [%d]th item not is.", i))
  1054  			}
  1055  		}
  1056  	}
  1057  	return res
  1058  }
  1059  
  1060  // ArrayPad 以指定长度将一个值item填充进arr数组/切片.
  1061  // 若 size 为正,则填补到数组的右侧,如果为负则从左侧开始填补;
  1062  // 若 size 的绝对值小于或等于 arr 数组的长度则没有任何填补.
  1063  func (ka *LkkArray) ArrayPad(arr interface{}, size int, item interface{}) []interface{} {
  1064  	val := reflect.ValueOf(arr)
  1065  	switch val.Kind() {
  1066  	case reflect.Array, reflect.Slice:
  1067  		length := val.Len()
  1068  		if length == 0 && size > 0 {
  1069  			return ka.SliceFill(item, size)
  1070  		}
  1071  
  1072  		orig := make([]interface{}, length)
  1073  		for i := 0; i < length; i++ {
  1074  			orig[i] = val.Index(i).Interface()
  1075  		}
  1076  
  1077  		if size == 0 || (size > 0 && size < length) || (size < 0 && size > -length) {
  1078  			return orig
  1079  		}
  1080  
  1081  		n := size
  1082  		if size < 0 {
  1083  			n = -size
  1084  		}
  1085  		n -= length
  1086  		items := make([]interface{}, n)
  1087  		for i := 0; i < n; i++ {
  1088  			items[i] = item
  1089  		}
  1090  
  1091  		if size > 0 {
  1092  			return append(orig, items...)
  1093  		}
  1094  		return append(items, orig...)
  1095  	default:
  1096  		panic("[ArrayPad]`arr type must be array|slice")
  1097  	}
  1098  }
  1099  
  1100  // ArrayRand 从数组(切片/字典)中随机取出num个元素.
  1101  func (ka *LkkArray) ArrayRand(arr interface{}, num int) []interface{} {
  1102  	val := reflect.ValueOf(arr)
  1103  	typ := val.Kind()
  1104  	if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Map {
  1105  		panic("[ArrayRand]`arr type must be array|slice|map")
  1106  	}
  1107  	if num < 1 {
  1108  		panic("[ArrayRand]`num cannot be less than 1")
  1109  	}
  1110  
  1111  	length := val.Len()
  1112  	if length == 0 {
  1113  		return nil
  1114  	}
  1115  	if num > length {
  1116  		num = length
  1117  	}
  1118  	res := make([]interface{}, num)
  1119  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
  1120  
  1121  	switch typ {
  1122  	case reflect.Array, reflect.Slice:
  1123  		for i, v := range r.Perm(length) {
  1124  			if i < num {
  1125  				res[i] = val.Index(v).Interface()
  1126  			} else {
  1127  				break
  1128  			}
  1129  		}
  1130  	case reflect.Map:
  1131  		var ks []reflect.Value
  1132  		for _, k := range val.MapKeys() {
  1133  			ks = append(ks, k)
  1134  		}
  1135  		for i, v := range r.Perm(length) {
  1136  			if i < num {
  1137  				res[i] = val.MapIndex(ks[v]).Interface()
  1138  			} else {
  1139  				break
  1140  			}
  1141  		}
  1142  	}
  1143  
  1144  	return res
  1145  }
  1146  
  1147  // CutSlice 裁剪切片,返回根据offset(起始位置)和size(数量)参数所指定的arr(数组/切片)中的一段切片.
  1148  func (ka *LkkArray) CutSlice(arr interface{}, offset, size int) []interface{} {
  1149  	if size < 1 {
  1150  		panic("[CutSlice]`size cannot be less than 1")
  1151  	}
  1152  
  1153  	val := reflect.ValueOf(arr)
  1154  	switch val.Kind() {
  1155  	case reflect.Array, reflect.Slice:
  1156  		length := val.Len()
  1157  		if length == 0 || (offset > 0 && offset > length-1) {
  1158  			return nil
  1159  		}
  1160  
  1161  		items := make([]interface{}, length)
  1162  		for i := 0; i < val.Len(); i++ {
  1163  			items[i] = val.Index(i).Interface()
  1164  		}
  1165  
  1166  		if offset < 0 {
  1167  			offset = offset%length + length
  1168  		}
  1169  		end := offset + size
  1170  		if end < length {
  1171  			return items[offset:end]
  1172  		}
  1173  		return items[offset:]
  1174  	default:
  1175  		panic("[CutSlice]`arr type must be array|slice")
  1176  	}
  1177  }
  1178  
  1179  // NewStrMapItf 新建[字符-接口]字典.
  1180  func (ka *LkkArray) NewStrMapItf() map[string]interface{} {
  1181  	return make(map[string]interface{})
  1182  }
  1183  
  1184  // NewStrMapStr 新建[字符-字符]字典.
  1185  func (ka *LkkArray) NewStrMapStr() map[string]string {
  1186  	return make(map[string]string)
  1187  }