上篇结构体排序的文档介绍了如果依据多个字段进行单因素排序, 举例来说, 一个学生实例, 可以单独按照姓名排序, 可以单独按照年龄排序, 可以单独按照体重排序. 本篇文章介绍如果进行多因素排序, 也就是按照姓名排序, 当姓名相同时, 按照年龄排序…
以官方文档的demo来做演示
1 | package main |
运行结果:
1 | By user: [{dmr C 100} {glenda Go 200} {gri Go 100} {gri Smalltalk 80} {ken C 150} {ken Go 200} {r Go 100} {r C 150} {rsc Go 200}] |
与上一篇文章<go语言结构体排序>(简称A)中<结构体多字段单独排序>的代码区别 (本篇简称B):
A:
1 | type By func(i, j student) bool |
B:
1 | type multiSorter struct { |
A B两篇中各截取了部分代码, 均涉及两项操作
- 生成数据集
- 排序
A篇的操作为: 单独声明一个By
数据类型, 为该数据类型编写方法, 方法中的第一步为生成数据集, 第二步为排序操作. 调用时By(name).Sort(students)
中的By(name)
是类型转换操作, 后续的.Sort()
方法是调用By
自己的Sort
方法得到的排序结果
B篇的操作为: 单独编写一个OrderBy
函数, 该OrderBy
函数仅用于生成数据集并返回, 需要注意的是, 这里生成的数据集, 仅包含有排序函数, 不包含实际数据. 由于数据集类型本身自带Sort
方法, 所以返回的数据可以直接调用Sort
方法执行排序操作, 排序之前, 将参数中的数据填充到数据集中, 形成完整的数据集. 调用时OrderedBy(user).Sort(changes)
中的OrderedBy(user)
与A篇不同, 此处不是类型转换, 而是函数调用, 后续的.Sort()
方法是由OrderedBy()
函数返回的multiSorter
对象, 调用multiSorter
中的Sort
方法得到的排序结果
A B两篇的排序方法略有差别, 但本质都是一样的, 核心操作都是生成数据集
和排序
, 只是B篇中, Less方法需要根据多因素排序, 略微复杂一些. 上面的例子是官方的demo, 当然我们也可以完全按照A篇的风格改写
1 | // 删除multiSorter数据类型中的Sort方法 |
这样修改之后, 调用方式也发生了变更
OrderedBy()
是一个类型转换的操作, 根据上面的声明, 它只能转换[]lessFunc
类型的数据, 所以需要先声明并赋值[]lessFunc{}
对象, 然后才能交给OrderedBy()
函数进行类型转换. 转换后其自身拥有Sort
方法可供调用
1 | OrderedBy([]lessFunc{user}).Sort(changes) |
以下是A篇风格的完整代码
1 | package main |