feat: 新增 utils/sher 包,包含了对 slice 及 hash 常用的操作函数。用于未来对 utils/slice 和 utils/hash 包进行替换

This commit is contained in:
kercylan98 2023-12-29 16:03:07 +08:00
parent a7b0497d4f
commit 515cbc66eb
8 changed files with 971 additions and 0 deletions

88
utils/sher/clone.go Normal file
View File

@ -0,0 +1,88 @@
package sher
import (
"slices"
)
// CloneMatrix 克隆二维数组
func CloneMatrix[S ~[][]V, V any](slice S) S {
if slice == nil {
return nil
}
var result = make(S, len(slice))
for i := 0; i < len(slice); i++ {
result[i] = CloneSlice(slice[i])
}
return result
}
// CloneSlice 克隆切片,该函数是 slices.Clone 的快捷方式
func CloneSlice[S ~[]V, V any](slice S) S {
return slices.Clone(slice)
}
// CloneMap 克隆 map
func CloneMap[M ~map[K]V, K comparable, V any](m M) M {
if m == nil {
return nil
}
var result = make(M, len(m))
for k, v := range m {
result[k] = v
}
return result
}
// CloneSliceN 克隆切片为 n 个切片进行返回
func CloneSliceN[S ~[]V, V any](slice S, n int) []S {
if slice == nil {
return nil
}
var result = make([]S, n)
for i := 0; i < n; i++ {
result[i] = CloneSlice(slice)
}
return result
}
// CloneMapN 克隆 map 为 n 个 map 进行返回
func CloneMapN[M ~map[K]V, K comparable, V any](m M, n int) []M {
if m == nil {
return nil
}
var result = make([]M, n)
for i := 0; i < n; i++ {
result[i] = CloneMap(m)
}
return result
}
// CloneSlices 克隆多个切片
func CloneSlices[S ~[]V, V any](slices ...S) []S {
if slices == nil {
return nil
}
var result = make([]S, len(slices))
for i, slice := range slices {
result[i] = CloneSlice(slice)
}
return result
}
// CloneMaps 克隆多个 map
func CloneMaps[M ~map[K]V, K comparable, V any](maps ...M) []M {
if maps == nil {
return nil
}
var result = make([]M, len(maps))
for i, m := range maps {
result[i] = CloneMap(m)
}
return result
}

308
utils/sher/contains.go Normal file
View File

@ -0,0 +1,308 @@
package sher
import "sort"
type ComparisonHandler[V any] func(source, target V) bool
// InSlice 判断切片中是否包含某个元素
func InSlice[S ~[]V, V any](slice S, v V, handler ComparisonHandler[V]) bool {
if slice == nil {
return false
}
for _, value := range slice {
if handler(v, value) {
return true
}
}
return false
}
// InSliceByBinarySearch 判断切片中是否包含某个元素,使用二分搜索
func InSliceByBinarySearch[S ~[]V, V any](slice S, v V, handler ComparisonHandler[V]) bool {
return sort.Search(len(slice), func(i int) bool {
return handler(v, slice[i])
}) != len(slice)
}
// AllInSlice 判断切片中是否包含所有元素
func AllInSlice[S ~[]V, V any](slice S, values []V, handler ComparisonHandler[V]) bool {
if slice == nil {
return false
}
for _, value := range values {
if !InSlice(slice, value, handler) {
return false
}
}
return true
}
// AllInSliceByBinarySearch 判断切片中是否包含所有元素,使用二分搜索
func AllInSliceByBinarySearch[S ~[]V, V any](slice S, values []V, handler ComparisonHandler[V]) bool {
if slice == nil {
return false
}
for _, value := range values {
if !InSliceByBinarySearch(slice, value, handler) {
return false
}
}
return true
}
// AnyInSlice 判断切片中是否包含任意一个元素
func AnyInSlice[S ~[]V, V any](slice S, values []V, handler ComparisonHandler[V]) bool {
if slice == nil {
return false
}
for _, value := range values {
if InSlice(slice, value, handler) {
return true
}
}
return false
}
// AnyInSliceByBinarySearch 判断切片中是否包含任意一个元素,使用二分搜索
func AnyInSliceByBinarySearch[S ~[]V, V any](slice S, values []V, handler ComparisonHandler[V]) bool {
if slice == nil {
return false
}
for _, value := range values {
if InSliceByBinarySearch(slice, value, handler) {
return true
}
}
return false
}
// InSlices 判断多个切片中是否包含某个元素
func InSlices[S ~[]V, V any](slices []S, v V, handler ComparisonHandler[V]) bool {
return InSlice(MergeSlices(slices...), v, handler)
}
// InSlicesByBinarySearch 判断多个切片中是否包含某个元素,使用二分搜索
func InSlicesByBinarySearch[S ~[]V, V any](slices []S, v V, handler ComparisonHandler[V]) bool {
return InSliceByBinarySearch(MergeSlices(slices...), v, handler)
}
// AllInSlices 判断多个切片中是否包含所有元素
func AllInSlices[S ~[]V, V any](slices []S, values []V, handler ComparisonHandler[V]) bool {
return AllInSlice(MergeSlices(slices...), values, handler)
}
// AllInSlicesByBinarySearch 判断多个切片中是否包含所有元素,使用二分搜索
func AllInSlicesByBinarySearch[S ~[]V, V any](slices []S, values []V, handler ComparisonHandler[V]) bool {
return AllInSliceByBinarySearch(MergeSlices(slices...), values, handler)
}
// AnyInSlices 判断多个切片中是否包含任意一个元素
func AnyInSlices[S ~[]V, V any](slices []S, values []V, handler ComparisonHandler[V]) bool {
return AnyInSlice(MergeSlices(slices...), values, handler)
}
// AnyInSlicesByBinarySearch 判断多个切片中是否包含任意一个元素,使用二分搜索
func AnyInSlicesByBinarySearch[S ~[]V, V any](slices []S, values []V, handler ComparisonHandler[V]) bool {
return AnyInSliceByBinarySearch(MergeSlices(slices...), values, handler)
}
// InAllSlices 判断元素是否在所有切片中都存在
func InAllSlices[S ~[]V, V any](slices []S, v V, handler ComparisonHandler[V]) bool {
if slices == nil {
return false
}
for _, slice := range slices {
if !InSlice(slice, v, handler) {
return false
}
}
return true
}
// InAllSlicesByBinarySearch 判断元素是否在所有切片中都存在,使用二分搜索
func InAllSlicesByBinarySearch[S ~[]V, V any](slices []S, v V, handler ComparisonHandler[V]) bool {
if slices == nil {
return false
}
for _, slice := range slices {
if !InSliceByBinarySearch(slice, v, handler) {
return false
}
}
return true
}
// AnyInAllSlices 判断元素是否在所有切片中都存在任意至少一个
func AnyInAllSlices[S ~[]V, V any](slices []S, v []V, handler ComparisonHandler[V]) bool {
if slices == nil {
return false
}
for _, slice := range slices {
if AnyInSlice(slice, v, handler) {
return true
}
}
return false
}
// AnyInAllSlicesByBinarySearch 判断元素是否在所有切片中都存在任意至少一个,使用二分搜索
func AnyInAllSlicesByBinarySearch[S ~[]V, V any](slices []S, v []V, handler ComparisonHandler[V]) bool {
if slices == nil {
return false
}
for _, slice := range slices {
if AnyInSliceByBinarySearch(slice, v, handler) {
return true
}
}
return false
}
// KeyInMap 判断 map 中是否包含某个 key
func KeyInMap[M ~map[K]V, K comparable, V any](m M, key K) bool {
_, ok := m[key]
return ok
}
// ValueInMap 判断 map 中是否包含某个 value
func ValueInMap[M ~map[K]V, K comparable, V any](m M, value V, handler ComparisonHandler[V]) bool {
if m == nil {
return false
}
for _, v := range m {
if handler(value, v) {
return true
}
}
return false
}
// AllKeyInMap 判断 map 中是否包含所有 key
func AllKeyInMap[M ~map[K]V, K comparable, V any](m M, keys ...K) bool {
if m == nil {
return false
}
for _, key := range keys {
if !KeyInMap(m, key) {
return false
}
}
return true
}
// AllValueInMap 判断 map 中是否包含所有 value
func AllValueInMap[M ~map[K]V, K comparable, V any](m M, values []V, handler ComparisonHandler[V]) bool {
if m == nil {
return false
}
for _, value := range values {
if !ValueInMap(m, value, handler) {
return false
}
}
return true
}
// AnyKeyInMap 判断 map 中是否包含任意一个 key
func AnyKeyInMap[M ~map[K]V, K comparable, V any](m M, keys ...K) bool {
if m == nil {
return false
}
for _, key := range keys {
if KeyInMap(m, key) {
return true
}
}
return false
}
// AnyValueInMap 判断 map 中是否包含任意一个 value
func AnyValueInMap[M ~map[K]V, K comparable, V any](m M, values []V, handler ComparisonHandler[V]) bool {
if m == nil {
return false
}
for _, value := range values {
if ValueInMap(m, value, handler) {
return true
}
}
return false
}
// AllKeyInMaps 判断多个 map 中是否包含所有 key
func AllKeyInMaps[M ~map[K]V, K comparable, V any](maps []M, keys ...K) bool {
if maps == nil {
return false
}
for _, m := range maps {
if !AllKeyInMap(m, keys...) {
return false
}
}
return true
}
// AllValueInMaps 判断多个 map 中是否包含所有 value
func AllValueInMaps[M ~map[K]V, K comparable, V any](maps []M, values []V, handler ComparisonHandler[V]) bool {
if maps == nil {
return false
}
for _, m := range maps {
if !AllValueInMap(m, values, handler) {
return false
}
}
return true
}
// AnyKeyInMaps 判断多个 map 中是否包含任意一个 key
func AnyKeyInMaps[M ~map[K]V, K comparable, V any](maps []M, keys ...K) bool {
if maps == nil {
return false
}
for _, m := range maps {
if AnyKeyInMap(m, keys...) {
return true
}
}
return false
}
// AnyValueInMaps 判断多个 map 中是否包含任意一个 value
func AnyValueInMaps[M ~map[K]V, K comparable, V any](maps []M, values []V, handler ComparisonHandler[V]) bool {
if maps == nil {
return false
}
for _, m := range maps {
if AnyValueInMap(m, values, handler) {
return true
}
}
return false
}
// InAllMaps 判断元素是否在所有 map 中都存在
func InAllMaps[M ~map[K]V, K comparable, V any](maps []M, key K) bool {
if maps == nil {
return false
}
for _, m := range maps {
if !KeyInMap(m, key) {
return false
}
}
return true
}
// AnyInAllMaps 判断元素是否在所有 map 中都存在任意至少一个
func AnyInAllMaps[M ~map[K]V, K comparable, V any](maps []M, keys []K) bool {
if maps == nil {
return false
}
for _, m := range maps {
if AnyKeyInMap(m, keys...) {
return true
}
}
return false
}

2
utils/sher/doc.go Normal file
View File

@ -0,0 +1,2 @@
// Package sher 用于对 slice 和 map 操作的工具函数,将逐步替代 utils/slice 和 utils/map
package sher

137
utils/sher/filter.go Normal file
View File

@ -0,0 +1,137 @@
package sher
// FilterOutByIndices 过滤切片中特定索引的元素,返回过滤后的切片
func FilterOutByIndices[S ~[]V, V any](slice S, indices ...int) S {
if slice == nil {
return nil
}
if len(indices) == 0 {
return slice
}
excludeMap := make(map[int]bool)
for _, ex := range indices {
excludeMap[ex] = true
}
validElements := make([]V, 0, len(slice)-len(excludeMap))
for i, v := range slice {
if !excludeMap[i] {
validElements = append(validElements, v)
}
}
return validElements
}
// FilterOutByCondition 过滤切片中符合条件的元素,返回过滤后的切片
// - condition 的返回值为 true 时,将会过滤掉该元素
func FilterOutByCondition[S ~[]V, V any](slice S, condition func(v V) bool) S {
if slice == nil {
return nil
}
if condition == nil {
return slice
}
validElements := make([]V, 0, len(slice))
for _, v := range slice {
if !condition(v) {
validElements = append(validElements, v)
}
}
return validElements
}
// FilterOutByKey 过滤 map 中特定的 key返回过滤后的 map
func FilterOutByKey[M ~map[K]V, K comparable, V any](m M, key K) M {
if m == nil {
return nil
}
validMap := make(M, len(m)-1)
for k, v := range m {
if k != key {
validMap[k] = v
}
}
return validMap
}
// FilterOutByValue 过滤 map 中特定的 value返回过滤后的 map
func FilterOutByValue[M ~map[K]V, K comparable, V any](m M, value V, handler ComparisonHandler[V]) M {
if m == nil {
return nil
}
validMap := make(M, len(m))
for k, v := range m {
if !handler(value, v) {
validMap[k] = v
}
}
return validMap
}
// FilterOutByKeys 过滤 map 中多个 key返回过滤后的 map
func FilterOutByKeys[M ~map[K]V, K comparable, V any](m M, keys ...K) M {
if m == nil {
return nil
}
if len(keys) == 0 {
return m
}
validMap := make(M, len(m)-len(keys))
for k, v := range m {
if !InSlice(keys, k, func(source, target K) bool {
return source == target
}) {
validMap[k] = v
}
}
return validMap
}
// FilterOutByValues 过滤 map 中多个 value返回过滤后的 map
func FilterOutByValues[M ~map[K]V, K comparable, V any](m M, values []V, handler ComparisonHandler[V]) M {
if m == nil {
return nil
}
if len(values) == 0 {
return m
}
validMap := make(M, len(m))
for k, v := range m {
if !InSlice(values, v, handler) {
validMap[k] = v
}
}
return validMap
}
// FilterOutByMap 过滤 map 中符合条件的元素,返回过滤后的 map
// - condition 的返回值为 true 时,将会过滤掉该元素
func FilterOutByMap[M ~map[K]V, K comparable, V any](m M, condition func(k K, v V) bool) M {
if m == nil {
return nil
}
if condition == nil {
return m
}
validMap := make(M, len(m))
for k, v := range m {
if condition(k, v) {
validMap[k] = v
}
}
return validMap
}

91
utils/sher/find.go Normal file
View File

@ -0,0 +1,91 @@
package sher
import "github.com/kercylan98/minotaur/utils/generic"
// FindMinimumInSlice 获取切片中的最小值
func FindMinimumInSlice[S ~[]V, V generic.Number](slice S, handler ComparisonHandler[V]) (result V) {
if slice == nil {
return
}
result = slice[0]
for i := 1; i < len(slice); i++ {
if handler(slice[i], result) {
result = slice[i]
}
}
return
}
// FindMaximumInSlice 获取切片中的最大值
func FindMaximumInSlice[S ~[]V, V generic.Number](slice S, handler ComparisonHandler[V]) (result V) {
if slice == nil {
return
}
result = slice[0]
for i := 1; i < len(slice); i++ {
if handler(result, slice[i]) {
result = slice[i]
}
}
return
}
// FindMin2MaxInSlice 获取切片中的最小值和最大值
func FindMin2MaxInSlice[S ~[]V, V generic.Number](slice S, handler ComparisonHandler[V]) (min, max V) {
if slice == nil {
return
}
min = slice[0]
max = slice[0]
for i := 1; i < len(slice); i++ {
if handler(slice[i], min) {
min = slice[i]
}
if handler(max, slice[i]) {
max = slice[i]
}
}
return
}
// FindMinFromMap 获取 map 中的最小值
func FindMinFromMap[M ~map[K]V, K comparable, V generic.Number](m M, handler ComparisonHandler[V]) (result V) {
if m == nil {
return
}
for _, v := range m {
if handler(v, result) {
result = v
}
}
return
}
// FindMaxFromMap 获取 map 中的最大值
func FindMaxFromMap[M ~map[K]V, K comparable, V generic.Number](m M, handler ComparisonHandler[V]) (result V) {
if m == nil {
return
}
for _, v := range m {
if handler(result, v) {
result = v
}
}
return
}
// FindMin2MaxFromMap 获取 map 中的最小值和最大值
func FindMin2MaxFromMap[M ~map[K]V, K comparable, V generic.Number](m M, handler ComparisonHandler[V]) (min, max V) {
if m == nil {
return
}
for _, v := range m {
if handler(v, min) {
min = v
}
if handler(max, v) {
max = v
}
}
return
}

56
utils/sher/merge.go Normal file
View File

@ -0,0 +1,56 @@
package sher
// MergeSlices 合并切片
func MergeSlices[S ~[]V, V any](slices ...S) (result S) {
if len(slices) == 0 {
return nil
}
var length int
for _, slice := range slices {
length += len(slice)
}
result = make(S, 0, length)
for _, slice := range slices {
result = append(result, slice...)
}
return
}
// MergeMaps 合并 map当多个 map 中存在相同的 key 时,后面的 map 中的 key 将会覆盖前面的 map 中的 key
func MergeMaps[M ~map[K]V, K comparable, V any](maps ...M) (result M) {
if len(maps) == 0 {
return nil
}
var length int
for _, m := range maps {
length += len(m)
}
result = make(M, length)
for _, m := range maps {
for k, v := range m {
result[k] = v
}
}
return
}
// MergeMapsWithSkip 合并 map当多个 map 中存在相同的 key 时,后面的 map 中的 key 将会被跳过
func MergeMapsWithSkip[M ~map[K]V, K comparable, V any](maps ...M) (result M) {
if len(maps) == 0 {
return nil
}
result = make(M)
for _, m := range maps {
for k, v := range m {
if _, ok := result[k]; !ok {
result[k] = v
}
}
}
return
}

239
utils/sher/random.go Normal file
View File

@ -0,0 +1,239 @@
package sher
import (
"fmt"
"github.com/kercylan98/minotaur/utils/random"
)
// ChooseRandomSliceElementRepeatN 获取切片中的 n 个随机元素,允许重复
// - 如果 n 大于切片长度或小于 0 时将会发生 panic
func ChooseRandomSliceElementRepeatN[S ~[]V, V any](slice S, n int) (result []V) {
if slice == nil {
return
}
if n > len(slice) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the slice or less than 0, n: %d, length: %d", n, len(slice)))
}
result = make([]V, n)
for i := 0; i < n; i++ {
result[i] = slice[random.Int(0, len(slice)-1)]
}
return
}
// ChooseRandomIndexRepeatN 获取切片中的 n 个随机元素的索引,允许重复
// - 如果 n 大于切片长度或小于 0 时将会发生 panic
func ChooseRandomIndexRepeatN[S ~[]V, V any](slice S, n int) (result []int) {
if slice == nil {
return
}
if n > len(slice) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the slice or less than 0, n: %d, length: %d", n, len(slice)))
}
result = make([]int, n)
for i := 0; i < n; i++ {
result[i] = random.Int(0, len(slice)-1)
}
return
}
// ChooseRandomSliceElement 获取切片中的随机元素
func ChooseRandomSliceElement[S ~[]V, V any](slice S) (v V) {
if slice == nil {
return
}
return slice[random.Int(0, len(slice)-1)]
}
// ChooseRandomIndex 获取切片中的随机元素的索引
func ChooseRandomIndex[S ~[]V, V any](slice S) (index int) {
if slice == nil {
return
}
return random.Int(0, len(slice)-1)
}
// ChooseRandomSliceElementN 获取切片中的 n 个随机元素
// - 如果 n 大于切片长度或小于 0 时将会发生 panic
func ChooseRandomSliceElementN[S ~[]V, V any](slice S, n int) (result []V) {
if slice == nil {
return
}
if n > len(slice) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the slice or less than 0, n: %d, length: %d", n, len(slice)))
}
result = make([]V, n)
for i := 0; i < n; i++ {
result[i] = slice[random.Int(0, len(slice)-1)]
}
return
}
// ChooseRandomIndexN 获取切片中的 n 个随机元素的索引
// - 如果 n 大于切片长度或小于 0 时将会发生 panic
func ChooseRandomIndexN[S ~[]V, V any](slice S, n int) (result []int) {
if slice == nil {
return
}
if n > len(slice) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the slice or less than 0, n: %d, length: %d", n, len(slice)))
}
result = make([]int, n)
for i := 0; i < n; i++ {
result[i] = random.Int(0, len(slice)-1)
}
return
}
// ChooseRandomMapKeyRepeatN 获取 map 中的 n 个随机 key允许重复
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyRepeatN[M ~map[K]V, K comparable, V any](m M, n int) (result []K) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the map or less than 0, n: %d, length: %d", n, len(m)))
}
result = make([]K, n)
for i := 0; i < n; i++ {
for k := range m {
result[i] = k
break
}
}
return
}
// ChooseRandomMapValueRepeatN 获取 map 中的 n 个随机 value允许重复
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapValueRepeatN[M ~map[K]V, K comparable, V any](m M, n int) (result []V) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the map or less than 0, n: %d, length: %d", n, len(m)))
}
result = make([]V, n)
for i := 0; i < n; i++ {
for _, v := range m {
result[i] = v
break
}
}
return
}
// ChooseRandomMapKeyAndValueRepeatN 获取 map 中的 n 个随机 key 和 value允许重复
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyAndValueRepeatN[M ~map[K]V, K comparable, V any](m M, n int) M {
if m == nil {
return nil
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the map or less than 0, n: %d, length: %d", n, len(m)))
}
result := make(M, n)
for i := 0; i < n; i++ {
for k, v := range m {
result[k] = v
break
}
}
return result
}
// ChooseRandomMapKey 获取 map 中的随机 key
func ChooseRandomMapKey[M ~map[K]V, K comparable, V any](m M) (k K) {
if m == nil {
return
}
for k = range m {
return
}
return
}
// ChooseRandomMapValue 获取 map 中的随机 value
func ChooseRandomMapValue[M ~map[K]V, K comparable, V any](m M) (v V) {
if m == nil {
return
}
for _, v = range m {
return
}
return
}
// ChooseRandomMapKeyN 获取 map 中的 n 个随机 key
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyN[M ~map[K]V, K comparable, V any](m M, n int) (result []K) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the map or less than 0, n: %d, length: %d", n, len(m)))
}
result = make([]K, n)
i := 0
for k := range m {
result[i] = k
i++
if i == n {
break
}
}
return
}
// ChooseRandomMapValueN 获取 map 中的 n 个随机 value
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapValueN[M ~map[K]V, K comparable, V any](m M, n int) (result []V) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the map or less than 0, n: %d, length: %d", n, len(m)))
}
result = make([]V, n)
i := 0
for _, v := range m {
result[i] = v
i++
if i == n {
break
}
}
return
}
// ChooseRandomMapKeyAndValue 获取 map 中的随机 key 和 value
func ChooseRandomMapKeyAndValue[M ~map[K]V, K comparable, V any](m M) (k K, v V) {
if m == nil {
return
}
for k, v = range m {
return
}
return
}
// ChooseRandomMapKeyAndValueN 获取 map 中的 n 个随机 key 和 value
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyAndValueN[M ~map[K]V, K comparable, V any](m M, n int) M {
if m == nil {
return nil
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("n is greater than the length of the map or less than 0, n: %d, length: %d", n, len(m)))
}
result := make(M, n)
i := 0
for k, v := range m {
result[k] = v
i++
if i == n {
break
}
}
return result
}

50
utils/sher/sort.go Normal file
View File

@ -0,0 +1,50 @@
package sher
import (
"github.com/kercylan98/minotaur/utils/generic"
"github.com/kercylan98/minotaur/utils/random"
"sort"
)
// Desc 对切片进行降序排序
func Desc[S ~[]V, V any, Sort generic.Ordered](slice *S, getter func(index int) Sort) {
sort.Slice(*slice, func(i, j int) bool {
return getter(i) > getter(j)
})
}
// DescByClone 对切片进行降序排序,返回排序后的切片
func DescByClone[S ~[]V, V any, Sort generic.Ordered](slice S, getter func(index int) Sort) S {
result := CloneSlice(slice)
Desc(&result, getter)
return result
}
// Asc 对切片进行升序排序
func Asc[S ~[]V, V any, Sort generic.Ordered](slice *S, getter func(index int) Sort) {
sort.Slice(*slice, func(i, j int) bool {
return getter(i) < getter(j)
})
}
// AscByClone 对切片进行升序排序,返回排序后的切片
func AscByClone[S ~[]V, V any, Sort generic.Ordered](slice S, getter func(index int) Sort) S {
result := CloneSlice(slice)
Asc(&result, getter)
return result
}
// Shuffle 对切片进行随机排序
func Shuffle[S ~[]V, V any](slice *S) {
sort.Slice(*slice, func(i, j int) bool {
return random.Int(0, 1) == 0
})
}
// ShuffleByClone 对切片进行随机排序,返回排序后的切片
func ShuffleByClone[S ~[]V, V any](slice S) S {
result := CloneSlice(slice)
Shuffle(&result)
return result
}