模块 4 · 第 5 课(共 5)课程中的20/50~10 min
模块课程(5/5)
使用 sort 包进行排序
标准 sort 包对切片进行就地排序。对于基本类型
(int, float64, string) 有直接的助手;对于您的任何其他切片
将 sort.Slice 与 less(i, j int) bool 函数一起使用,该函数定义
订购。
基本类型的助手
Go
import "sort"
nums := []int{5, 2, 8, 1}
sort.Ints(nums) // [1 2 5 8]
words := []string{"c", "a", "b"}
sort.Strings(words) // [a b c]
fs := []float64{1.5, 0.5, 2.5}
sort.Float64s(fs) // [0.5 1.5 2.5]排序是就地:原始切片已发生变化。
sort.Slice:自定义排序
您传递切片和一个 less 函数,给定两个索引 i 和
j,如果元素 i 应位于 j 之前,则返回 true:
Go
type Person struct {
Name string
Age int
}
people := []Person{
{"Bruno", 30},
{"Anna", 25},
{"Carla", 28},
}
sort.Slice(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})
// Anna(25), Carla(28), Bruno(30)要反向排序,只需翻转比较即可:
return people[i].Age > people[j].Age。
稳定排序
sort.Slice 不保证稳定(“相等”元素可能会改变
相对顺序)。对于稳定的排序,请使用 sort.SliceStable:
Go
sort.SliceStable(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})按多个键排序
常见模式:按年龄排序,年龄相等则按姓名排序:
Go
sort.Slice(people, func(i, j int) bool {
if people[i].Age != people[j].Age {
return people[i].Age < people[j].Age
}
return people[i].Name < people[j].Name
})二分查找
sort.SearchInts / sort.Search 处理已排序的切片:
Go
nums := []int{1, 3, 5, 7, 9}
i := sort.SearchInts(nums, 5) // 2如果该元素不存在,则返回插入索引。你可以挖 当您需要时了解详细信息。
泛型(Go 1.21+):slices.Sort
来自 stdlib 中的 slices 包(Go 1.21):
Go
import "slices"
nums := []int{3, 1, 2}
slices.Sort(nums) // [1 2 3]
slices.SortFunc(people, func(a, b Person) int {
return a.Age - b.Age // -1/0/1
})更现代、类型安全的 API。与 sort.Slice 兼容,但更多
符合人体工学。
尝试一下
锻炼#go.m4.l5.e1
尝试:0加载中...
使用 sort.Ints 对 nums 进行升序排序。
正在加载编辑器...
显示提示
`sort.Ints` 对 int 切片进行就地排序。
3 次尝试后可用的解决方案
锻炼#go.m4.l5.e2
尝试:0加载中...
使用 sort.Slice 按年龄升序对人员进行排序。
正在加载编辑器...
显示提示
当元素 i 应该出现在 j 之前时,less 函数返回 true。
3 次尝试后可用的解决方案
Quiz#go.m4.l5.e3
准备好如何使用 sort.Slice 按降序排序?
Go
sort.Slice(s, func(i, j int) bool { return ??? })回顾
sort.Ints/sort.Strings/sort.Float64s用于基本类型,就地。sort.Slice(s, less)适用于任何类型的切片,带有less(i, j)函数。sort.SliceStable保留相等键的相对顺序。- 按多个键排序:
less内的if级联。 - Go 1.21+:带有通用 API 的
slices软件包(slices.Sort、slices.SortFunc)。 - 对于地图键:提取到切片并排序。