1 Star 1 Fork 0

李爽 / go-utils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
slice.go 3.77 KB
一键复制 编辑 原始数据 按行查看 历史
李爽 提交于 2024-03-16 11:04 . 修改切片排序函数
package utils
import (
"errors"
"fmt"
"math"
"reflect"
"sort"
)
// SlicePagination 表示包含所有必要元数据的分页结果。
type SlicePagination[T any] struct {
Page int // 当前页
PageSize int // 每页条数
Total int // 总条数
TotalPages int // 总页数
Items []T // 当前页的数据
HasPrevPage bool // 是否有上一页
HasNextPage bool // 是否有下一页
}
// PaginateSlice 获取任何类型的切片、页码和页面大小,并返回 SlicePagination.
func PaginateSlice[T any](items []T, page, pageSize int) SlicePagination[T] {
if page == 0 {
page = 1
}
if pageSize == 0 {
pageSize = 10
}
total := len(items)
totalPages := int(math.Ceil(float64(total) / float64(pageSize)))
start := (page - 1) * pageSize
end := start + pageSize
// 如果结束索引超过项目总数,则调整结束索引
if end > total {
end = total
}
// 如果 start 大于项目总数,则返回 Items 的空切片
if start > total {
start = total
}
return SlicePagination[T]{
Page: page,
PageSize: pageSize,
Total: total,
TotalPages: totalPages,
Items: items[start:end],
HasPrevPage: page > 1,
HasNextPage: page < totalPages,
}
}
// CopySlice
// 复制切片为不同的引用(深拷贝)
// T为切片元素
func CopySlice[T any](original []T) []T {
newSlice := make([]T, len(original))
copy(newSlice, original)
return newSlice
}
// SortStructs
// 对结构体切片进行排序
// T为结构体
func SortStructs[T any](slice []T, fieldName string, ascending bool) error {
lessFunc, err := makeLessFunc(slice, fieldName)
if err != nil {
return err
}
sort.SliceStable(slice, func(i, j int) bool {
vi := reflect.ValueOf(slice[i]).FieldByName(fieldName)
vj := reflect.ValueOf(slice[j]).FieldByName(fieldName)
if ascending {
return lessFunc(vi.Interface(), vj.Interface())
} else {
return lessFunc(vj.Interface(), vi.Interface())
}
})
return nil
}
func makeLessFunc[T any](slice []T, fieldName string) (func(value1, value2 any) bool, error) {
if len(slice) == 0 {
return nil, errors.New("slice is empty, can't determine the type of fieldName")
}
fieldValue := reflect.ValueOf(slice[0]).FieldByName(fieldName)
if !fieldValue.IsValid() {
return nil, fmt.Errorf("field %s not found in the struct", fieldName)
}
switch fieldValue.Interface().(type) {
case int:
return func(value1, value2 any) bool {
return value1.(int) < value2.(int)
}, nil
case int8:
return func(value1, value2 any) bool {
return value1.(int8) < value2.(int8)
}, nil
case int16:
return func(value1, value2 any) bool {
return value1.(int16) < value2.(int16)
}, nil
case int32:
return func(value1, value2 any) bool {
return value1.(int32) < value2.(int32)
}, nil
case int64:
return func(value1, value2 any) bool {
return value1.(int64) < value2.(int64)
}, nil
case uint:
return func(value1, value2 any) bool {
return value1.(uint) < value2.(uint)
}, nil
case uint8:
return func(value1, value2 any) bool {
return value1.(uint8) < value2.(uint8)
}, nil
case uint16:
return func(value1, value2 any) bool {
return value1.(uint16) < value2.(uint16)
}, nil
case uint32:
return func(value1, value2 any) bool {
return value1.(uint32) < value2.(uint32)
}, nil
case uint64:
return func(value1, value2 any) bool {
return value1.(uint64) < value2.(uint64)
}, nil
case float32:
return func(value1, value2 any) bool {
return value1.(float32) < value2.(float32)
}, nil
case float64:
return func(value1, value2 any) bool {
return value1.(float64) < value2.(float64)
}, nil
case string:
return func(value1, value2 any) bool {
return value1.(string) < value2.(string)
}, nil
default:
return nil, errors.New("unsupported type for comparison")
}
}
Go
1
https://gitee.com/love_bass/go-utils.git
git@gitee.com:love_bass/go-utils.git
love_bass
go-utils
go-utils
v0.7.8

搜索帮助