package sli import ( "fmt" "math/rand" "reflect" "go.mongodb.org/mongo-driver/bson/primitive" ) // 将任意切片类型转换为 []interface{} func CreateAnyTypeSlice(slice interface{}) []interface{} { //判断是否是切片类型 v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { return nil } sliceLen := v.Len() out := make([]interface{}, sliceLen) for i := 0; i < sliceLen; i++ { out[i] = v.Index(i).Interface() } return out } // @brief: 删除任意切片类型指定下标的元素 func Delete(slice interface{}, index int) (interface{}, bool) { //判断是否是切片类型 v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { return nil, false } //参数检查 if v.Len() == 0 || index < 0 || index > v.Len()-1 { return nil, false } return reflect.AppendSlice(v.Slice(0, index), v.Slice(index+1, v.Len())).Interface(), true } // @brief: 删除任意切片类型指定范围下标的元素 func DeleteIndexRange(slice interface{}, start, end int) (interface{}, bool) { //判断是否是切片类型 v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { return nil, false } //参数检查 if v.Len() == 0 || start < 0 || end > v.Len()-1 { return nil, false } if start == 0 && end == 0 { return nil, true } return reflect.AppendSlice(v.Slice(0, start-1), v.Slice(end+1, v.Len())).Interface(), true } // @brief: 删除任意切片类型指定的元素 , 0 表示删除匹配到的第一个元素,1 表示删除匹配到的所有元素 func DeleteSpecifyEle(slice interface{}, spec interface{}, ct ...int) interface{} { //判断是否是切片类型 isAll := false v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { return slice } //参数检查 if v.Len() == 0 { return slice } if len(ct) == 0 { isAll = false } else if ct[0] == 0 { isAll = false } else if ct[0] == 1 { isAll = true } var handleSlice interface{} handleSlice = slice for i := 0; i < v.Len(); i++ { fmt.Println(reflect.ValueOf(v.Index(i).Interface()), reflect.ValueOf(spec)) if reflect.ValueOf(v.Index(i).Interface()) == reflect.ValueOf(spec) { out, suc := Delete(handleSlice, i) handleSlice = out if suc { if !isAll { return out } } } } return handleSlice } // 给任意切片类型插入元素 func Insert(slice interface{}, index int, value interface{}) (interface{}, bool) { //判断是否是切片类型 v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { return nil, false } //参数检查 if index < 0 || index > v.Len() || reflect.TypeOf(slice).Elem() != reflect.TypeOf(value) { return nil, false } //尾部追加元素 if index == v.Len() { return reflect.Append(v, reflect.ValueOf(value)).Interface(), true } v = reflect.AppendSlice(v.Slice(0, index+1), v.Slice(index, v.Len())) v.Index(index).Set(reflect.ValueOf(value)) return v.Interface(), true } // 给任意字符串类型数组插入元素 func InsertStringSlice(slice []string, index int, value ...string) []string { var newStr []string if index == 0 { return append(append(newStr, value...), slice...) } if index == len(slice)-1 { return append(append(newStr, slice...), value...) } return append(append(append(newStr, slice[0:index]...), value...), slice[index:]...) } // 修改任意切片类型指定下标的元素 func Update(slice interface{}, index int, value interface{}) (interface{}, bool) { //判断是否是切片类型 v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { return nil, false } //参数检查 if index > v.Len()-1 || reflect.TypeOf(slice).Elem() != reflect.TypeOf(value) { return nil, false } v.Index(index).Set(reflect.ValueOf(value)) return v.Interface(), true } // 查找指定元素在任意切片类型中的所有下标 func Search(slice interface{}, value interface{}) ([]int, bool) { //判断是否是切片类型 v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { return nil, false } index := make([]int, 0, v.Len()) for i := 0; i < v.Len(); i++ { if v.Index(i).Interface() == reflect.ValueOf(value).Interface() { index = append(index, i) } } return index, true } // 元素去重 func RemoveRep[T comparable](slc []T) []T { if len(slc) < 1024 { // 切片长度小于1024的时候,循环来过滤 return RemoveRepByLoop(slc) } // 大于的时候,通过map来过滤 return RemoveRepByMap(slc) } // 通过map主键唯一的特性过滤重复元素 func RemoveRepByMap[T comparable](slc []T) []T { result := []T{} tempMap := map[T]byte{} // 存放不重复主键 for _, e := range slc { l := len(tempMap) tempMap[e] = 0 if len(tempMap) != l { // 加入map后,map长度变化,则元素不重复 result = append(result, e) } } return result } // 通过map主键唯一的特性过滤重复元素: uint64 func RemoveRepUintByMap(slc []uint64) []uint64 { result := []uint64{} tempMap := map[uint64]byte{} // 存放不重复主键 for _, e := range slc { l := len(tempMap) tempMap[e] = 0 if len(tempMap) != l { // 加入map后,map长度变化,则元素不重复 result = append(result, e) } } return result } // 通过两重循环过滤重复元素 func RemoveRepByLoop[T comparable](slc []T) []T { result := make([]T, 0, len(slc)) // 存放结果 for i := range slc { flag := true for j := range result { if slc[i] == result[j] { flag = false // 存在重复元素,标识为false break } } if flag { // 标识为false,不添加进结果 result = append(result, slc[i]) } } return result } // RemoveRepObjectID 过滤重复 mongo ID func RemoveRepObjectID(slc []primitive.ObjectID) []primitive.ObjectID { res := []primitive.ObjectID{} m := make(map[primitive.ObjectID]struct{}) for _, v := range slc { if _, ok := m[v]; !ok { m[v] = struct{}{} res = append(res, v) } } return res } // objID切片是否存在item func PrimitiveObjIDIsExist(slc []primitive.ObjectID, item primitive.ObjectID) bool { flag := false for i := range slc { if slc[i] == item { flag = true break } } return flag } // 是否包含某一个元素 func Contains[T comparable](slc []T, item T) bool { flag := false for i := range slc { if slc[i] == item { flag = true break } } return flag } func ContainsUint(slc []uint64, item uint64) bool { flag := false for i := range slc { if slc[i] == item { flag = true break } } return flag } func ContainsInt(slc []int, item int) bool { flag := false for i := range slc { if slc[i] == item { flag = true break } } return flag } func Shuffle(slice []interface{}) { for len(slice) > 0 { n := len(slice) randIndex := rand.Intn(n) slice[n-1], slice[randIndex] = slice[randIndex], slice[n-1] slice = slice[:n-1] } } func ShuffleString(slice []string) { for len(slice) > 0 { n := len(slice) randIndex := rand.Intn(n) slice[n-1], slice[randIndex] = slice[randIndex], slice[n-1] slice = slice[:n-1] } } // InSlice 判断元素是否存在于数组中 func InSlice[T any | primitive.ObjectID](i T, s []T) bool { for _, ii := range s { if reflect.DeepEqual(i, ii) { return true } } return false }