项目地址:https://github.com/Mustenaka/Go-simpleSort
改进的Golang排序工具
本工程主要是go在1.18 Bate1版本之前没有引入范型概念,每一次使用Sort排序都要声明一堆东西,想要实现类似其他语言那样的任意排序而构件的,通过反射实现了自定义输入的数据,然后声明需要排序的资源,进行自动排序,随着Go的版本逐步深入
代码:
package simplesort
import (
"fmt"
"reflect"
"sort"
"github.com/Mustenaka/Go-simpleSort/sortConfig"
)
type SortBy []interface{}
func (a SortBy) Len() int { return len(a) }
func (a SortBy) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a SortBy) Less(i, j int) bool {
// Get Sort index
sortIndex := sortConfig.GetInstance().GetIndex()
// 定位比较字段
fieldValue1 := reflect.ValueOf(a[i]).Field(sortIndex)
fieldValue2 := reflect.ValueOf(a[j]).Field(sortIndex)
// 断言类型
switch fieldValue1.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return fieldValue1.Int() < fieldValue2.Int()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return fieldValue1.Uint() < fieldValue2.Uint()
case reflect.Float32, reflect.Float64:
return fieldValue1.Float() < fieldValue2.Float()
case reflect.String:
return fieldValue1.String() < fieldValue2.String()
default:
panic("unsupported kind")
}
}
// @title Simplesort
// @description simplified non-generic sort method.
// @param data interface{} "Data to be sorted."
// @param filedName string "sorted index field name."
// @param order bool "oder or reverse order"
// @return interface{}, error "sort results, nil if no error."
func Simplesort(args interface{}, filedName string, order bool) ([]interface{}, error) {
// 输出数据
fmt.Println("input: ", args)
// interface{} convert to []interface{}
var interfaceSlice []interface{}
// 判断类型
if reflect.TypeOf(args).Kind() != reflect.Slice {
panic("input need slice kind")
}
// 输出类型信息
fmt.Println("args typeof kind: " + reflect.TypeOf(args).Kind().String())
// 定位目标字段在结构体中的索引
var index int = 0
// 切片处理
s := reflect.ValueOf(args)
for i := 0; i < s.Len(); i++ {
ele := s.Index(i)
t := ele.Type()
interfaceSlice = append(interfaceSlice, ele.Interface())
// 检查需要排序字段是否包含在结构体中
var isExist bool = false
for ii := 0; ii < ele.NumField(); ii++ {
// fmt.Printf("name: %s, type: %s, value: %v\n",
// t.Field(ii).Name,
// ele.Field(ii).Type(),
// ele.Field(ii))
if t.Field(ii).Name == filedName {
isExist = true
index = ii
}
}
// 未找到需要排序的字段,抛出错误
if !isExist {
// panic("not found filed: " + filedName)
return nil, fmt.Errorf("not found filed: %s", filedName)
}
}
// 处理完成,初始化排序的配置 - 用单例的方式注入Less方法
sortConfig.CreateInstance(index, filedName, order)
// 对结构体数组进行排序
sort.Sort(SortBy(interfaceSlice))
// 输出数据
fmt.Println("output: ", interfaceSlice)
return interfaceSlice, nil
}
// @title SimplesortStable
// @description reflect test
func FunctionTest(data interface{}) {
getValue := reflect.ValueOf(data) // Value of v
if getValue.Kind() != reflect.Slice {
panic("need slice kind")
}
l := getValue.Len()
for i := 0; i < l; i++ {
value := getValue.Index(i) // Value of item
typel := value.Type() // Type of item
if typel.Kind() != reflect.Struct {
panic("need struct kind")
}
fmt.Printf("type-kind: %s, type-name: %s, value: %v\n", typel.Kind(), typel.Name(), value.Interface())
num := value.NumField()
for j := 0; j < num; j++ {
fmt.Printf("name: %s, type: %s, value: %v\n",
typel.Field(j).Name,
value.Field(j).Type(),
value.Field(j))
}
}
}
// 单例模式测试
func SinTest(filedName string) {
sortConfig.CreateInstance(2, filedName, true)
fmt.Println("instance: ", sortConfig.GetInstance().GetIndex())
fmt.Println("instance: ", sortConfig.GetInstance().GetName())
fmt.Println("instance: ", sortConfig.GetInstance().GetOrder())
}
1 条评论
golang 自定义结构体排序 – 木十的博客 · 2022年7月20日 下午9:59
[…] 改进的Golang排序库-Golang简单排序 […]