Go语言排序与接口实例分析

作者:计算机教程

您可能感兴趣的文章:


import "fmt"
type Sorter interface {
  Len() int
  Less(i, j int) bool
  Swap(i, j int)
}
type Xi []int
type Xs []string
func (p Xi) Len() int { return len(p) }
func (p Xi) Less(i int, j int) bool { return p[j] < p[i] }
func (p Xi) Swap(i int, j int) { p[i], p[j] = p[j], p[i] }
func (p Xs) Len() int { return len(p) }
func (p Xs) Less(i int, j int) bool { return p[j] < p[i] }
func (p Xs) Swap(i int, j int) { p[i], p[j] = p[j], p[i] }
func Sort(x Sorter) {
  for i := 0; i < x.Len() - 1; i {
    for j := i 1; j < x.Len(); j {
      if x.Less(i, j) {
        x.Swap(i, j)
      }
    }
  }
}
func main() {
  ints := Xi{44, 67, 3, 17, 89, 10, 73, 9, 14, 8}
  strings := Xs{"nut", "ape", "elephant", "zoo", "go"}
  Sort(ints)
  fmt.Printf("%vn", ints)
  Sort(strings)
  fmt.Printf("%vn", strings)
}

补注: 近来又看 go 的排序, 发现以前对 go 的排序理解的有点浅了。 go 的排序思路和 c 和 c 有些差别。 c 默认是对数组进行排序, c 是对一个序列进行排序, go 则更宽泛一些,待排序的可以是任何对象, 虽然很多情况下是一个 slice (分片, 类似于数组),或是包含 slice 的一个对象。

复制代码 代码如下:

 

本文实例讲述了Go语言排序与接口用法。分享给大家供大家参考。具体如下:

 

希望本文所述对大家的Go语言程序设计有所帮助。

结构体排序方法 2

 

方法 1 的缺点是 : 根据 Age 排序需要重新定义 PersonSlice 方法,绑定 Len 、 Less 和 Swap 方法, 如果需要根据 Name 排序, 又需要重新写三个函数; 如果结构体有 4 个字段,有四种类型的排序,那么就要写 3 × 4 = 12 个方法, 即使有一些完全是多余的, O__O"… 仔细思量一下,根据不同的标准 Age 或是 Name, 真正不同的体现在 Less 方法上,所以, me 们将 Less 抽象出来, 每种排序的 Less 让其变成动态的,比如下面一种方法。

 

  1. package main

  2.  

  3. import (

  4.     "fmt"

  5.     "sort"

  6. )

  7.  

  8. type Person struct {

  9.     Name string    // 姓名

  10.     Age  int    // 年纪

  11. }

  12.  

  13. type PersonWrapper struct {

  14.     people [] Person

  15.     by func(p, q * Person) bool

  16. }

  17.  

  18. func (pw PersonWrapper) Len() int {    // 重写 Len() 方法

  19.     return len(pw.people)

  20. }

  21. func (pw PersonWrapper) Swap(i, j int){     // 重写 Swap() 方法

  22.     pw.people[i], pw.people[j] = pw.people[j], pw.people[i]

  23. }

  24. func (pw PersonWrapper) Less(i, j int) bool {    // 重写 Less() 方法

  25.     return pw.by(&pw.people[i], &pw.people[j])

  26. }

  27.  

  28. func main() {

  29.     people := [] Person{

  30.         {"zhang san", 12},

  31.         {"li si", 30},

  32.         {"wang wu", 52},

  33.         {"zhao liu", 26},

  34.     }

  35.  

  36.     fmt.Println(people)

  37.  

  38.     sort.Sort(PersonWrapper{people, func (p, q *Person) bool {

  39.         return q.Age < p.Age    // Age 递减排序

  40.     }})

  41.  

  42.     fmt.Println(people)

  43.     sort.Sort(PersonWrapper{people, func (p, q *Person) bool {

  44.         return p.Name < q.Name    // Name 递增排序

  45.     }})

  46.  

  47.     fmt.Println(people)

  48.  

  49. }

 

方法 2 将 [] Person 和比较的准则 cmp 封装在了一起,形成了 PersonWrapper 函数,然后在其上绑定 Len 、 Less 和 Swap 方法。 实际上 sort.Sort(pw) 排序的是 pw 中的 people, 这就是前面说的, go 的排序未必就是针对的一个数组或是 slice, 而可以是一个对象中的数组或是 slice 。

 

结构体排序方法 1

 

  1. package main

  2.  

  3. import (

  4.     "fmt"

  5.     "sort"

  6. )

  7.  

  8. type Person struct {

  9.     Name string    // 姓名

  10.     Age  int    // 年纪

  11. }

  12.  

  13. // 按照 Person.Age 从大到小排序

  14. type PersonSlice [] Person

  15.  

  16. func (a PersonSlice) Len() int {    // 重写 Len() 方法

  17.     return len(a)

  18. }

  19. func (a PersonSlice) Swap(i, j int){     // 重写 Swap() 方法

  20.     a[i], a[j] = a[j], a[i]

  21. }

  22. func (a PersonSlice) Less(i, j int) bool {    // 重写 Less() 方法, 从大到小排序

  23.     return a[j].Age < a[i].Age 

  24. }

  25.  

  26. func main() {

  27.     people := [] Person{

  28.         {"zhang san", 12},

  29.         {"li si", 30},

  30.         {"wang wu", 52},

  31.         {"zhao liu", 26},

  32.     }

  33.  

  34.     fmt.Println(people)

  35.  

  36.     sort.Sort(PersonSlice(people))    // 按照 Age 的逆序排序

  37.     fmt.Println(people)

  38.  

  39.     sort.Sort(sort.Reverse(PersonSlice(people)))    // 按照 Age 的升序排序

  40.     fmt.Println(people)

  41.  

  42. }

 

这完全是一种模拟的方式,所以如果懂了 IntSlice 自然就理解这里了,反过来,理解了这里那么 IntSlice 那里也就懂了。

 

原文:https://studygolang.com/articles/1598

 

 

结构体排序方法 3

 

me 赶脚方法 2 已经很不错了, 唯一一个缺点是,在 main 中使用的时候暴露了 sort.Sort 的使用,还有就是 PersonWrapper 的构造。 为了让 main 中使用起来更为方便, me 们可以再简单的封装一下, 构造一个 SortPerson 方法, 如下:

 

  1. package main

  2.  

  3. import (

  4.     "fmt"

  5.     "sort"

  6. )

  7.  

  8. type Person struct {

  9.     Name string    // 姓名

  10.     Age  int    // 年纪

  11. }

  12.  

  13. type PersonWrapper struct {

  14.     people [] Person

  15.     by func(p, q * Person) bool

  16. }

  17.  

  18. type SortBy func(p, q *Person) bool

  19.  

  20. func (pw PersonWrapper) Len() int {    // 重写 Len() 方法

  21.     return len(pw.people)

  22. }

  23. func (pw PersonWrapper) Swap(i, j int){     // 重写 Swap() 方法

  24.     pw.people[i], pw.people[j] = pw.people[j], pw.people[i]

  25. }

  26. func (pw PersonWrapper) Less(i, j int) bool {    // 重写 Less() 方法

  27.     return pw.by(&pw.people[i], &pw.people[j])

  28. }

  29.  

  30.  

  31. func SortPerson(people []nba买球, Person, by SortBy){    // SortPerson 方法

  32.     sort.Sort(PersonWrapper{people, by})

  33. }

  34.  

  35. func main() {

  36.     people := [] Person{

  37.         {"zhang san", 12},

  38.         {"li si", 30},

  39.         {"wang wu", 52},

  40.         {"zhao liu", 26},

  41.     }

  42.  

  43.     fmt.Println(people)

  44.  

  45.     sort.Sort(PersonWrapper{people, func (p, q *Person) bool {

  46.         return q.Age < p.Age    // Age 递减排序

  47.     }})

  48.  

  49.     fmt.Println(people)

  50.  

  51.     SortPerson(people, func (p, q *Person) bool {

  52.         return p.Name < q.Name    // Name 递增排序

  53.     })

  54.  

  55.     fmt.Println(people)

  56.  

  57. }

 

在方法 2 的基础上构造了 SortPerson 函数,使用的时候传过去一个 [] Person 和一个 cmp 函数。

 

基本类型 int 、 float64 和 string 的排序

 

 

本文由nba买球发布,转载请注明来源

关键词: