package utils import ( "golang.org/x/exp/constraints" "sort" ) func SliceConstruct[T any](fn func() T) T { return fn() } type SliceWalkCallback func(index int) bool // true 继续 func SliceWalk(length int, cb SliceWalkCallback) { for i := 0; i < length; i++ { if ok := cb(i); ok { continue } else { break } } } type SliceIncludeFilter func(index int) bool // 返回 true 继续, false 中断 func SliceInclude(length int, filter SliceIncludeFilter) (int, bool) { for i := 0; i < length; i++ { if ok := filter(i); ok { return i, true } } return -1, false } type SliceConstructNFilter[T any] func(index int) (T, bool) // 返回 是否保留,项值 func SliceConstructN[T any](length int, filter SliceConstructNFilter[T]) []T { ret := make([]T, 0) for i := 0; i < length; i++ { if item, keep := filter(i); keep { ret = append(ret, item) } } return ret } // SliceUnique 使用泛型实现切片去重 func SliceUnique[T comparable](s []T) []T { seen := make(map[T]bool) j := 0 for _, v := range s { if _, ok := seen[v]; !ok { seen[v] = true s[j] = v j++ } } return s[:j] } // SlicesDifference 求两个集合的差集 func SlicesDifference[T comparable](a, b []T) []T { // 使用 map 存储集合 b 的元素,方便快速判断元素是否存在 seen := make(map[T]struct{}, len(b)) for _, v := range b { seen[v] = struct{}{} } // 遍历集合 a,将不在集合 b 中的元素放入新的切片 diff := make([]T, 0) for _, v := range a { if _, ok := seen[v]; !ok { diff = append(diff, v) } } return diff } func RemoveSlicesElement[T comparable](slice []T, element T) []T { // 使用两个指针,一个遍历,一个用来记录有效元素的位置 j := 0 for i := range slice { if slice[i] != element { slice[j] = slice[i] j++ } } // 返回截取后的切片 return slice[:j] } func SlicesIntersect[T constraints.Ordered | ~string](slice1, slice2 []T) []T { dict := make(map[T]int) ret := make([]T, 0) for _, v1 := range slice1 { dict[v1]++ } for _, v2 := range slice2 { if _, exists := dict[v2]; exists { ret = append(ret, v2) } } return ret } func IsSliceEqual[T constraints.Ordered](src []T, dst []T) bool { sort.Slice(src, func(i, j int) bool { return src[i] < src[j] }) sort.Slice(dst, func(i, j int) bool { return dst[i] < dst[j] }) if len(src) != len(dst) { return false } for i := range src { if src[i] != dst[i] { return false } } return true }