@@ -0,0 +1,116 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user