type Interface

一个满足sort.Interface接口的(集合)类型可以被本包的函数进行排序。方法要求集合中的元素可以被整数索引

  1. type Interface interface {
  2. // Len方法返回集合中的元素个数
  3. Len() int
  4. // Less方法报告索引i的元素是否比索引j的元素小
  5. Less(i, j int) bool
  6. // Swap方法交换索引i和j的两个元素
  7. Swap(i, j int)
  8. }

type IntSlice

  1. type IntSlice []int
  2. func (p IntSlice) Len() int
  3. func (p IntSlice) Less(i, j int) bool
  4. func (p IntSlice) Swap(i, j int)
  5. func (p IntSlice) Sort() // Sort等价于调用Sort(p)
  6. func (p IntSlice) Search(x int) int // Search等价于调用SearchInts(p, x)

type Float64Slice

  1. type Float64Slice []float64
  2. func (p IntSlice) Len() int
  3. func (p IntSlice) Less(i, j int) bool
  4. func (p IntSlice) Swap(i, j int)
  5. func (p IntSlice) Sort() //Sort等价于调用Sort(p)
  6. func (p IntSlice) Search(x int) int //Search等价于调用SearchFloat64s(p, x)

type StringSlice

  1. type StringSlice []string
  2. func (p StringSlice) Len() int
  3. func (p StringSlice) Less(i, j int) bool
  4. func (p StringSlice) Swap(i, j int)
  5. func (p StringSlice) Sort() //Sort等价于调用Sort(p)
  6. func (p StringSlice) Search(x string) int //Search等价于调用SearchStrings(p, x)

包方法

func Sort(data Interface) Sort排序data,不保证稳定性

func Stable(data Interface) 排序data,并保证排序的稳定性
func IsSorted(data Interface) bool IsSorted报告data是否已经被排序
func Reverse(data Interface) Interface 包装一个Interface接口并返回一个新的Interface接口,递减序列

  1. s := []int{5, 2, 6, 3, 1, 4} // unsorted
  2. sort.Sort(sort.Reverse(sort.IntSlice(s)))
  3. fmt.Println(s)
  4. [6 5 4 3 2 1]

func Slice(x interface{}, less func(i, j int) bool) 根据提供的less的函数对切片x进行排序。如果x不是切片,它就会恐慌

  1. func main() {
  2. people := []struct {
  3. Name string
  4. Age int
  5. }{
  6. {"Gopher", 7},
  7. {"Alice", 55},
  8. {"Vera", 24},
  9. {"Bob", 75},
  10. }
  11. sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
  12. fmt.Println("By name:", people)
  13. sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
  14. fmt.Println("By age:", people)
  15. }

func SliceIsSorted(x interface{}, less func(i, j int) bool) bool 报告切片x是否根据提供的less函数排序。如果x不是切片,它就会恐慌。
func SliceStable(x interface{}, less func(i, j int) bool) 使用提供的less函数对切片x进行排序,保持相同元素的原始顺序。如果x不是切片,它就会恐慌。

func Search(n int, f func(int) bool) int 采用二分法搜索找到[0, n)区间内最小的满足f(i)==true的值i

  1. 一个更古怪的例子,下面的程序会猜测你持有的数字:
  2. func GuessingGame() {
  3. var s string
  4. fmt.Printf("Pick an integer from 0 to 100.\n")
  5. answer := sort.Search(100, func(i int) bool {
  6. fmt.Printf("Is your number <= %d? ", i)
  7. fmt.Scanf("%s", &s)
  8. return s != "" && s[0] == 'y'
  9. })
  10. fmt.Printf("Your number is %d.\n", answer)
  11. }

func Ints(a []int) 将a排序为递增顺序

  1. s := []int{5, 2, 6, 3, 1, 4} // unsorted
  2. sort.Ints(s)
  3. fmt.Println(s)
  4. [1 2 3 4 5 6]

func IntsAreSorted(a []int) bool 检查a是否已排序为递增顺序
func SearchInts(a []int, x int) int 在递增顺序的a中搜索x,返回x的索引。如果查找不到,返回值是x应该插入a的位置(以保证a的递增顺序),返回值可以是len(a)。
func Float64s(a []float64)
func Float64sAreSorted(a []float64) bool
func SearchFloat64s(a []float64, x float64) int
func Strings(a []string)
func StringsAreSorted(a []string) bool
func SearchStrings(a []string, x string) int

自定义实现

简单

  1. package sort_test
  2. import (
  3. "fmt"
  4. "sort"
  5. )
  6. type Person struct {
  7. Name string
  8. Age int
  9. }
  10. func (p Person) String() string {
  11. return fmt.Sprintf("%s: %d", p.Name, p.Age)
  12. }
  13. type ByAge []Person
  14. func (a ByAge) Len() int { return len(a) }
  15. func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
  16. func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
  17. func Example() {
  18. people := []Person{
  19. {"Bob", 31},
  20. {"John", 42},
  21. {"Michael", 17},
  22. {"Jenny", 26},
  23. }
  24. fmt.Println(people)
  25. sort.Sort(ByAge(people))
  26. fmt.Println(people)
  27. // Output:
  28. // [Bob: 31 John: 42 Michael: 17 Jenny: 26]
  29. // [Michael: 17 Jenny: 26 Bob: 31 John: 42]
  30. }

sortkeys

  1. package sort_test
  2. import (
  3. "fmt"
  4. "sort"
  5. )
  6. // A couple of type definitions to make the units clear.
  7. type earthMass float64
  8. type au float64
  9. // A Planet defines the properties of a solar system object.
  10. type Planet struct {
  11. name string
  12. mass earthMass
  13. distance au
  14. }
  15. // By is the type of a "less" function that defines the ordering of its Planet arguments.
  16. type By func(p1, p2 *Planet) bool
  17. // Sort is a method on the function type, By, that sorts the argument slice according to the function.
  18. func (by By) Sort(planets []Planet) {
  19. ps := &planetSorter{
  20. planets: planets,
  21. by: by, // The Sort method's receiver is the function (closure) that defines the sort order.
  22. }
  23. sort.Sort(ps)
  24. }
  25. // planetSorter joins a By function and a slice of Planets to be sorted.
  26. type planetSorter struct {
  27. planets []Planet
  28. by func(p1, p2 *Planet) bool // Closure used in the Less method.
  29. }
  30. // Len is part of sort.Interface.
  31. func (s *planetSorter) Len() int {
  32. return len(s.planets)
  33. }
  34. // Swap is part of sort.Interface.
  35. func (s *planetSorter) Swap(i, j int) {
  36. s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
  37. }
  38. // Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
  39. func (s *planetSorter) Less(i, j int) bool {
  40. return s.by(&s.planets[i], &s.planets[j])
  41. }
  42. var planets = []Planet{
  43. {"Mercury", 0.055, 0.4},
  44. {"Venus", 0.815, 0.7},
  45. {"Earth", 1.0, 1.0},
  46. {"Mars", 0.107, 1.5},
  47. }
  48. // ExampleSortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.
  49. func Example_sortKeys() {
  50. // Closures that order the Planet structure.
  51. name := func(p1, p2 *Planet) bool {
  52. return p1.name < p2.name
  53. }
  54. mass := func(p1, p2 *Planet) bool {
  55. return p1.mass < p2.mass
  56. }
  57. distance := func(p1, p2 *Planet) bool {
  58. return p1.distance < p2.distance
  59. }
  60. decreasingDistance := func(p1, p2 *Planet) bool {
  61. return !distance(p1, p2)
  62. }
  63. // Sort the planets by the various criteria.
  64. By(name).Sort(planets)
  65. fmt.Println("By name:", planets)
  66. By(mass).Sort(planets)
  67. fmt.Println("By mass:", planets)
  68. By(distance).Sort(planets)
  69. fmt.Println("By distance:", planets)
  70. By(decreasingDistance).Sort(planets)
  71. fmt.Println("By decreasing distance:", planets)
  72. // Output: By name: [{Earth 1 1} {Mars 0.107 1.5} {Mercury 0.055 0.4} {Venus 0.815 0.7}]
  73. // By mass: [{Mercury 0.055 0.4} {Mars 0.107 1.5} {Venus 0.815 0.7} {Earth 1 1}]
  74. // By distance: [{Mercury 0.055 0.4} {Venus 0.815 0.7} {Earth 1 1} {Mars 0.107 1.5}]
  75. // By decreasing distance: [{Mars 0.107 1.5} {Earth 1 1} {Venus 0.815 0.7} {Mercury 0.055 0.4}]
  76. }