Files
rootandClaude Opus 4.7 79ac89b458 Initial commit
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-11-07 10:47:18 +08:00

117 lines
2.4 KiB
Go

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
}