go项目中根据结构体的某个字段进行排序
通常来说有两种方法
- sort.Slice()方法:
package main
import (
"fmt"
"sort"
)
// 对结构体指定字段进行排序
type User struct {
Name string `json:"name"` // `json:"xxx"`:在结构体和json字符串字段顺序不一致的情况下:unmarshal根据tag去寻找对应字段的内容
Age int `json:"age"`
}
// type Users []User
// func SortByAge(u Users) {
func SortByAge(u []User) {
fmt.Printf("源数据:%+v\n", u)
sort.Slice(u, func(i, j int) bool { // desc
return u[i].Age > u[j].Age
})
fmt.Printf("按Age降序:%+v\n", u)
sort.Slice(u, func(i, j int) bool { // asc
return u[i].Age < u[j].Age
})
fmt.Printf("按Age升序:%+v\n", u)
}
func main() {
// 初始化结构体对象数组:
// 初始化方法1:
// users := Users{
// {
// Name: "test1",
// Age: 22,
// },
// {
// Name: "test2",
// Age: 19,
// },
// {
// Name: "test3",
// Age: 25,
// },
// }
// 初始化方法2:
var users []User
var u User
u.Name = "test1"
u.Age = 22
users = append(users, u)
u.Name = "test2"
u.Age = 20
users = append(users, u)
u.Name = "test3"
u.Age = 26
users = append(users, u)
SortByAge(users)
}
// 输出:
源数据:[{Name:test1 Age:22} {Name:test2 Age:20} {Name:test3 Age:26}]
按Age降序:[{Name:test3 Age:26} {Name:test1 Age:22} {Name:test2 Age:20}]
按Age升序:[{Name:test2 Age:20} {Name:test1 Age:22} {Name:test3 Age:26}]
但是该方法在我的项目中使用时,确实会改变原有的顺序,但是并没有达到预期,控制台也没有报错,debug是发现这个错误unreadable protocol error E08 during memory read for packet
- sort.Sort()方法
package main
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
type Persons []Person
// Len()方法和Swap()方法不用变化
// 获取此 slice 的长度
func (p Persons) Len() int { return len(p) }
// 交换数据
func (p Persons) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// 嵌套结构体 将继承 Person 的所有属性和方法
// 所以相当于SortByName 也实现了 Len() 和 Swap() 方法
type SortByName struct{ Persons }
// 根据元素的姓名长度降序排序 (此处按照自己的业务逻辑写)
func (p SortByName) Less(i, j int) bool {
return len(p.Persons[i].Name) > len(p.Persons[j].Name)
}
type SortByAge struct{ Persons }
// 根据元素的年龄降序排序 (此处按照自己的业务逻辑写)
func (p SortByAge) Less(i, j int) bool {
return p.Persons[i].Age > p.Persons[j].Age
}
func main() {
persons := Persons{
{
Name: "test123",
Age: 20,
},
{
Name: "test1",
Age: 22,
},
{
Name: "test12",
Age: 21,
},
}
fmt.Println("排序前")
for _, person := range persons {
fmt.Println(person.Name, ":", person.Age)
}
sort.Sort(SortByName{persons})
fmt.Println("排序后")
for _, person := range persons {
fmt.Println(person.Name, ":", person.Age)
}
}
该方法可以达到预期