golang中使用 sort.Interface 实现复杂多级排序

举两个例子,说明 sort.Interface实现多级排序。

例子 1

学生成绩排序(先按成绩降序,成绩相同按姓名升序)

复制代码
  package main

  import (
      "fmt"
      "sort"
  )

  type Student struct {
      Name  string
      Score int
  }

  type ByScoreAndName []Student

  func (s ByScoreAndName) Len() int {
      return len(s)
  }

  func (s ByScoreAndName) Swap(i, j int) {
      s[i], s[j] = s[j], s[i]
  }

  func (s ByScoreAndName) Less(i, j int) bool {
      // 第一级:按分数降序(分数高的排前面)
      if s[i].Score != s[j].Score {
          return s[i].Score > s[j].Score
      }
      // 第二级:分数相同时,按姓名升序
      return s[i].Name < s[j].Name
  }

  func main() {
      students := []Student{
          {"Alice", 85},
          {"Bob", 90},
          {"Charlie", 85},
          {"David", 90},
      }

      sort.Sort(ByScoreAndName(students))

      for _, s := range students {
          fmt.Printf("%s: %d\n", s.Name, s.Score)
      }
      // 输出:
      // Bob: 90
      // David: 90
      // Alice: 85
      // Charlie: 85
  }

例子 2

员工排序(先按部门升序,部门相同按工资降序,工资相同按工号升序)

复制代码
  package main

  import (
      "fmt"
      "sort"
  )

  type Employee struct {
      ID         int
      Department string
      Salary     float64
  }

  type ByDeptSalaryID []Employee

  func (e ByDeptSalaryID) Len() int {
      return len(e)
  }

  func (e ByDeptSalaryID) Swap(i, j int) {
      e[i], e[j] = e[j], e[i]
  }

  func (e ByDeptSalaryID) Less(i, j int) bool {
      // 第一级:按部门升序
      if e[i].Department != e[j].Department {
          return e[i].Department < e[j].Department
      }
      // 第二级:部门相同时,按工资降序
      if e[i].Salary != e[j].Salary {
          return e[i].Salary > e[j].Salary
      }
      // 第三级:工资相同时,按工号升序
      return e[i].ID < e[j].ID
  }

  func main() {
      employees := []Employee{
          {103, "Engineering", 75000},
          {101, "Engineering", 80000},
          {102, "Engineering", 80000},
          {201, "Sales", 70000},
          {202, "Sales", 75000},
      }

      sort.Sort(ByDeptSalaryID(employees))

      for _, emp := range employees {
          fmt.Printf("ID: %d, Dept: %s, Salary: %.2f\n",
              emp.ID, emp.Department, emp.Salary)
      }
      // 输出:
      // ID: 101, Dept: Engineering, Salary: 80000.00
      // ID: 102, Dept: Engineering, Salary: 80000.00
      // ID: 103, Dept: Engineering, Salary: 75000.00
      // ID: 202, Dept: Sales, Salary: 75000.00
      // ID: 201, Dept: Sales, Salary: 70000.00
  }
相关推荐
afumu13 分钟前
Go 写一个只监听 127.0.0.1 的控制服务:鉴权、白名单、危险命令拦截
后端·安全·go
johnjincaaaa1 小时前
猿人学第 18 题「jsvmp 洞察先机」逆向通关实录
javascript·后端
用户4702784004051 小时前
C语言编译与链接
后端·开源
你三大爷1 小时前
从 Hessian 迁移到 protostuff:深嵌套模型反序列化耗时与高并发类加载锁的根治实战
后端·架构
IT枫斗者枫哥1 小时前
子线程断言失败,JUnit 为什么还显示通过?
java·后端
码农小河663 小时前
基于PHP的电商后台蜜罐系统
开发语言·php
starzy19903 小时前
深入理解Scala柯里化函数:函数链式变换
开发语言·scala
stark张宇3 小时前
Vibe Coding 入门实战:用 Claude Code 跑通 AI 产品开发流程(上)
后端·claude·vibecoding
ShineWinsu3 小时前
对于Qt:QTreeWidget常见属性以及QTreeWidgetItem类的解析
开发语言·c++·qt·gui·客户端·多叉树·qtreewidget
落羽的落羽3 小时前
【C++】C++17的主要特性
linux·服务器·开发语言·c++·算法·机器学习