package collect import ( "cmp" "maps" "sort" ) func In[T comparable](value T, values ...T) bool { if len(values) == 0 { return false } for _, v := range values { if value == v { return true } } return false } func NotIn[T comparable](value T, values ...T) bool { return !In(value, values...) } func Count[T any](slice []T, isCount func(int, T) bool) (count int) { for i, item := range slice { if isCount(i, item) { count++ } } return } // Filter 从切片过滤元素返回新切片 // predicate 返回true保留 func Filter[T any](slice []T, predicate func(T) bool) []T { var res []T for _, item := range slice { if predicate(item) { res = append(res, item) } } return res } // Remove 移除原切片元素 // predicate 返回true移除 func Remove[T any](slice *[]T, predicate func(T) bool) (removes int) { writeIndex := 0 for _, item := range *slice { if predicate(item) { removes++ } else { (*slice)[writeIndex] = item writeIndex++ } } *slice = (*slice)[:writeIndex] return } func Uniq[T comparable, Slice ~[]T](collection Slice) Slice { result := make(Slice, 0, len(collection)) seen := make(map[T]struct{}, len(collection)) for i := range collection { if _, ok := seen[collection[i]]; ok { continue } seen[collection[i]] = struct{}{} result = append(result, collection[i]) } return result } func Find[T any](slice []T, predicate func(T) bool) (r T, ok bool) { for _, item := range slice { if predicate(item) { return item, true } } return } func FindIndex[T any](slice []T, predicate func(T) bool) (i int, ok bool) { for i, item := range slice { if predicate(item) { return i, true } } return } // SortAsc 切片升序排序 func SortAsc[T any, C cmp.Ordered](slice []T, compare func(T) C) { if len(slice) < 2 { return } sort.Slice(slice, func(i, j int) bool { return compare(slice[i]) < compare(slice[j]) }) } // SortDesc 切片降序排序 func SortDesc[T any, C cmp.Ordered](slice []T, compare func(T) C) { if len(slice) < 2 { return } sort.Slice(slice, func(i, j int) bool { return compare(slice[i]) > compare(slice[j]) }) } // Tail 获取切片尾部元素 // dv: 空切片默认值 func Tail[T any](slice []T, dv T) T { if len(slice) == 0 { return dv } return slice[len(slice)-1] } func MapKeys[K comparable, V any](kvs map[K]V) (keys []K) { if len(kvs) == 0 { return } keys = make([]K, 0, len(kvs)) for k := range kvs { keys = append(keys, k) } return } func MapValues[K comparable, V any](kvs map[K]V) (values []V) { if len(kvs) == 0 { return values } values = make([]V, 0, len(kvs)) for _, v := range kvs { values = append(values, v) } return } func Map2Slice[K comparable, V any, T any](kvs map[K]V, fn func(k K, v V) T) (values []T) { if len(kvs) == 0 { return values } values = make([]T, 0, len(kvs)) for k, v := range kvs { values = append(values, fn(k, v)) } return } func Sum[T int32 | int64 | int](nums []T) T { var sum T = 0 for _, num := range nums { sum += num } return sum } func MustMax[T any, C cmp.Ordered](slice []T, compare func(T) C) (max T) { if len(slice) == 0 { panic("MustMax slice length 0") } max = slice[0] if len(slice) == 1 { return } maxC := compare(max) for i := 1; i < len(slice); i++ { if c := compare(slice[i]); cmp.Compare(c, maxC) > 0 { max = slice[i] maxC = c } } return } func Slice2Map[T any, K comparable](slice []T, k func(int, T) K) map[K]T { if slice == nil { return make(map[K]T, 0) } m := make(map[K]T, len(slice)) for i, item := range slice { m[k(i, item)] = item } return m } func Slice2MapKv[T any, K comparable, V any](slice []T, mapping func(int, T) (K, V)) map[K]V { if slice == nil { return make(map[K]V, 0) } m := make(map[K]V, len(slice)) for i, item := range slice { k, v := mapping(i, item) m[k] = v } return m } func Mapping[T any, V any](slice []T, mapping func(T) V) (vs []V) { vs = make([]V, 0, len(slice)) for _, item := range slice { vs = append(vs, mapping(item)) } return } func Mapping0[T any, V any](slice []T, mapping func(int, T) V) (vs []V) { vs = make([]V, 0, len(slice)) for i, item := range slice { vs = append(vs, mapping(i, item)) } return } // SliceEquals compare slice all element equals func SliceEquals[T comparable](slice1 []T, slice2 []T) bool { if len(slice1) != len(slice2) { return false } for i, ele := range slice1 { if ele != slice2[i] { return false } } return true } func CopyMap[K comparable, V any](src map[K]V) (dst map[K]V) { dst = make(map[K]V, len(src)) maps.Copy(dst, src) return } func MappingIndex[T any](slice []T) (index []int) { index = make([]int, len(slice)) for i := range slice { index[i] = i } return } func SortIndex[T any](slice []T, less func(i, j int) bool) (sortIndex []int) { sortIndex = MappingIndex(slice) sort.Slice(sortIndex, func(i, j int) bool { return less(sortIndex[i], sortIndex[j]) }) return } func Reverse[T any](slice []T) { length := len(slice) for i := range length / 2 { offset := length - 1 - i slice[i], slice[offset] = slice[offset], slice[i] } }