首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

golang struct数组通用排序

2024-12-20 来源:化拓教育网

因为自定义的结构体数组需要重新实现 Len() Swap() Less()函数,这样只要有个新的结构体数组就需要再copy一遍代码,投机之后就有了以下“一劳永逸”的代码,结构体再多也不“通用”。

//通用排序
//结构体排序,必须重写数组Len() Swap() Less()函数
type body_wrapper struct {
    Bodys [] interface{}
    by func(p,q*interface{}) bool //内部Less()函数会用到
}
type SortBodyBy func(p, q* interface{}) bool //定义一个函数类型

//数组长度Len()
func (acw body_wrapper) Len() int  {
    return len(acw.Bodys)
}
//元素交换
func (acw body_wrapper) Swap(i,j int){
    acw.Bodys[i],acw.Bodys[j] = acw.Bodys[j],acw.Bodys[i]
}
//比较函数,使用外部传入的by比较函数
func (acw body_wrapper) Less(i,j int) bool {
    return acw.by(&acw.Bodys[i],&acw.Bodys[j])
}
//自定义排序字段,参考SortBodyByCreateTime中的传入函数
func SortBody(bodys [] interface{}, by SortBodyBy){
    sort.Sort(body_wrapper{bodys,by})
}
//按照createtime排序,需要注意是否有createtime
func SortBodyByCreateTime(bodys [] interface{}){
    sort.Sort(body_wrapper{bodys,func(p,q * interface{}) bool{
        v :=reflect.ValueOf(*p)
        i := v.FieldByName("Create_time")
        v =reflect.ValueOf(*q)
        j := v.FieldByName("Create_time")
        return  i.String() > j.String()
    }})
}

较之一般的结构体数组排序,这里结合了结构体映射去做了排序,所以无需关心结构体类型;
使用方式:

type User struct  {
    Name string `json:"name"`
    Create_time string `json:"create_time"`
}

func main() {
    results := []interface{}{} //这里必须定义成[]interface{}{}
    u1 := User{
        Name:"lxw",
        Create_time:"2018-02-01",
    }
    u2 := User{
        Name:"zll",
        Create_time:"2018-03-01",
    }
    results = append(results,u1)
    results = append(results,u2)
    //使用定义好的排序
    SortBodyByCreateTime(results)
    fmt.Println(results)
    // 使用自定义的字段排序
    SortBody(results,func(p,q * interface{}) bool{
        v :=reflect.ValueOf(*p)
        i := v.FieldByName("Name")
        v =reflect.ValueOf(*q)
        j := v.FieldByName("Name")
        return  i.String() < j.String()
    })
    fmt.Println(results)
}

输出结果如下:

[{ zll 2018-03-01} { lxw 2018-02-01}]
[{ lxw 2018-02-01} { zll 2018-03-01}]

Process finished with exit code 0
显示全文