golang 结构体实现 sort.Interface 接口

slice 类型要能实现排序,只需实现 sort.Interface 接口即可,但是 slice 类型并非唯一能实现 sort.Interface 接口的类型,这篇文章就介绍结构体如何实现 sort.Interface 接口来对结构体 slice 类型字段排序。这样可以达到多字段排序的目的,而不仅仅局限一个单一字段。看看下面这个例子,我们希望按 Title 排序,如果 Title 相同,再按 Visited 排序,看看如何实现。先两个结构体的定义,与 sort.Interface 接口实现:

type Article struct {
Title string
Desc string
Visited int
}

type ArticleSort struct {
g []*Article
less func(x, y *Article) bool
}

func (s ArticleSort) Len() int { return len(s.g) }
func (s ArticleSort) Less(i, j int) bool { return s.less(s.g[i], s.g[j]) }
func (s ArticleSort) Swap(i, j int) { s.g[i], s.g[j] = s.g[j], s.g[i] }

 

结构体 ArticleSort 字段 g 排序,这里定义了一个匿名函数,匿名函数中根据 Title,Visited 排序

sort.Sort(ArticleSort{groups, func(x, y *Article) bool {
if x.Title != y.Title {
return x.Title < y.Title
}
if x.Visited != y.Visited {
return x.Visited < y.Visited
}
return false
}})

 

全量代码,它是如何对结构体字段 g 就地排序

package main

import (
"fmt"
"sort"
)

func main() {
groups := []*Article{
{"Golang", "Hi, golang.", 30},
{"Python", "Oh, python.", 20},
{"Java", "SHit, java.", 19},
{"Python", "Oh, python, It is good.", 43},
{"Java", "SHit, java, it is bad.", 21},
{"Golang", "Hi, golang, my love.", 13},
{"Ruby", "Fuck, ruby.", 25}}

sort.Sort(ArticleSort{groups, func(x, y *Article) bool {
if x.Title != y.Title {
return x.Title < y.Title
}
if x.Visited != y.Visited {
return x.Visited < y.Visited
}
return false
}})

for _, g := range groups {
fmt.Printf("%s\t%d\t%s\n", g.Title, g.Visited, g.Desc)
}
}

type Article struct {
Title string
Desc string
Visited int
}

type ArticleSort struct {
g []*Article
less func(x, y *Article) bool
}

func (s ArticleSort) Len() int { return len(s.g) }
func (s ArticleSort) Less(i, j int) bool { return s.less(s.g[i], s.g[j]) }
func (s ArticleSort) Swap(i, j int) { s.g[i], s.g[j] = s.g[j], s.g[i] }

 

输出结果


F:\github.com\iissy\goexample\sort2>go run main.go
Golang  13      Hi, golang, my love.
Golang  30      Hi, golang.
Java    19      SHit, java.
Java    21      SHit, java, it is bad.
Python  20      Oh, python.
Python  43      Oh, python, It is good.
Ruby    25      Fuck, ruby.

上篇文章介绍了 slice 排序,https://www.hrefs.cn/article/go-sort-Interface-to-sort-any-sequence,我们可以比较它们的异同。

Posted by 何敏 on 2020-03-04 11:00:55