跳转到主要内容
模块 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)。
  • 对于地图键:提取到切片并排序。