You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
3.9 KiB
208 lines
3.9 KiB
package collect |
|
|
|
import ( |
|
"cmp" |
|
"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 |
|
} |
|
|
|
func Filter[T any](slice []T, predicate func(int, T) bool) []T { |
|
var res []T |
|
for i, item := range slice { |
|
if predicate(i, item) { |
|
res = append(res, item) |
|
} |
|
} |
|
return res |
|
} |
|
|
|
// 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(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)) |
|
for k, v := range src { |
|
dst[k] = v |
|
} |
|
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] |
|
} |
|
}
|
|
|