美文网首页golang我爱编程
golang struct数组通用排序

golang struct数组通用排序

作者: 李孝伟 | 来源:发表于2018-06-14 16:07 被阅读198次

    因为自定义的结构体数组需要重新实现 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
    

    相关文章

      网友评论

        本文标题:golang struct数组通用排序

        本文链接:https://www.haomeiwen.com/subject/wiuyeftx.html