Golang如何根据任意指定列的值对二维数组进行排序
Go 实现二维数组按指定列排序
需求说明
给定N行M列的二维数组,以及列号K(取值范围1<=K<=M,列号从1开始计数),对二维数组的行按照第K列的数值做升序排序。
示例
输入(4×4二维数组):
39 27 11 42 10 93 91 90 54 78 56 89 24 64 20 65
按第3列值排序后的输出:
39 27 11 42 24 64 20 65 54 78 56 89 10 93 91 90
实现逻辑
Go标准库sort包的排序能力需要目标类型实现Len、Swap、Less三个方法,由于排序需要依赖指定列号这个参数,我们先自定义一个类型把二维数组和排序列号封装到一起:
// MatrixSorter 二维数组排序器 type MatrixSorter struct { matrix [][]int // 待排序的二维数组 sortCol int // 排序依据的列号,注意是0起始索引 }
接着依次实现三个接口方法:
Len():返回待排序元素总数,也就是二维数组的行数
func (m MatrixSorter) Len() int { return len(m.matrix) }
Swap(i,j int):交换下标为i、j的两个元素,这里直接交换二维数组的两行即可
func (m MatrixSorter) Swap(i, j int) { m.matrix[i], m.matrix[j] = m.matrix[j], m.matrix[i] }
Less(i,j int) bool:定义排序比较规则,这里比较两行在指定排序列上的数值大小,返回true代表i行应该排在j行前面
func (m MatrixSorter) Less(i, j int) bool { return m.matrix[i][m.sortCol] < m.matrix[j][m.sortCol] }
完整可运行示例
注意传入的列号K是从1开始计数的,初始化排序器时要减1转成切片用的0起始索引,避免索引越界或者排错列。
package main import ( "fmt" "sort" ) type MatrixSorter struct { matrix [][]int sortCol int } func (m MatrixSorter) Len() int { return len(m.matrix) } func (m MatrixSorter) Swap(i, j int) { m.matrix[i], m.matrix[j] = m.matrix[j], m.matrix[i] } func (m MatrixSorter) Less(i, j int) bool { return m.matrix[i][m.sortCol] < m.matrix[j][m.sortCol] } func main() { // 示例输入二维数组 matrix := [][]int{ {39, 27, 11, 42}, {10, 93, 91, 90}, {54, 78, 56, 89}, {24, 64, 20, 65}, } K := 3 // 指定按第3列排序(1起始计数) // 初始化排序器,列号转0起始索引 sort.Sort(MatrixSorter{ matrix: matrix, sortCol: K - 1, }) // 打印排序结果 for _, row := range matrix { for _, val := range row { fmt.Printf("%d ", val) } fmt.Println() } }
补充说明
- 如果需要降序排序,只需要把
Less方法里的<比较符换成>即可 - 如果待排序数组是
float64、string等其他类型,只需要把matrix字段的元素类型对应替换,比较逻辑保持一致即可 - 该实现是原地排序,排序后直接修改原二维数组的行顺序,不需要额外申请整份数组的内存空间
内容的提问来源于stack exchange,提问作者ninja
相关产品推荐
相关产品推荐

