【问题标题】:sorting a uint64 slice in go在 go 中对一个 uint64 切片进行排序
【发布时间】:2016-12-01 03:44:06
【问题描述】:

我正在使用 Go 1.7rc3 编写 Go 应用程序。

我有一块 uint64 (var dirRange []uint64) 想要排序。

排序包有一个函数sort.Ints(),但它需要[]int,而我有[]uint64

我该怎么办?我可以输入所有切片吗?

谢谢

【问题讨论】:

    标签: go slice


    【解决方案1】:

    从 1.8 版开始,您可以使用更简单的函数 sort.Slice。在您的情况下,它将类似于以下内容:

    sort.Slice(dirRange, func(i, j int) bool { return dirRange[i] < dirRange[j] })
    

    这避免了为排序定义任何类型。

    【讨论】:

    • 我不能自己编辑,因为它少于6个字符,但是你给Slice的第二个参数,比较函数需要声明索引参数ij
    • 对于好奇的人:golang 中的 int 依赖于平台并已签名 (golang.org/doc/go1.1#int)。有符号的 64 位范围非常大,在对大量切片进行排序时并不是真正的限制
    【解决方案2】:

    你可以在你的dirRange上定义sort.Interface,它可以是一个类型别名[]uint64

    type DirRange []uint64
    
    func (a DirRange) Len() int           { return len(a) }
    func (a DirRange) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    func (a DirRange) Less(i, j int) bool { return a[i] < a[j] }
    
    func main() {
        dirRange := DirRange{2, 5, 7, 1, 9, 4}
        sort.Sort(dirRange)
        fmt.Println(dirRange)   
    }
    

    输出:

    [1 2 4 5 7 9]
    

    这样您可以避免强制转换并直接使用您的数组。由于底层类型是切片[]uint64,您仍然可以使用一般切片操作。例如:

    dirRange := make(DirRange, 10)
    dirRange = append(dirRange, 2)
    

    【讨论】:

      【解决方案3】:

      您可以为[]uint64提供一个类型别名,添加标准的“样板”排序方法来实现sort.interfaceLenSwapLess-https://golang.org/pkg/sort/#Interface);然后创建新类型的实例或将现有切片 []uint64 类型转换为新类型,如以下示例中所做的那样(也是 https://play.golang.org/p/BbB3L9TmBI):

      package main
      
      import (
          "fmt"
          "sort"
      )
      
      type uint64arr []uint64
      
      func (a uint64arr) Len() int           { return len(a) }
      func (a uint64arr) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
      func (a uint64arr) Less(i, j int) bool { return a[i] < a[j] }
      func (a uint64arr) String() (s string) {
          sep := "" // for printing separating commas
          for _, el := range a {
              s += sep
              sep = ", "
              s += fmt.Sprintf("%d", el)
          }
          return
      }
      
      func main() {
          dirRange := []uint64{3, 2, 400000}
          arr := uint64arr(dirRange)
          sort.Sort(arr)
          fmt.Printf("%s\n", arr)
          fmt.Printf("%#v\n", dirRange)
      }
      

      输出是:

      2, 3, 400000
      []uint64{0x2, 0x3, 0x61a80}
      

      显示两个数组都已排序,因为第二个数组是原始数组的类型转换别名。

      【讨论】:

        【解决方案4】:

        没有wrapper函数,需要用到Slice函数,这是一个例子:

        arr := []uint64{5, 0, 3, 2, 1, 6}
        
        sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })
        

        【讨论】:

          猜你喜欢
          • 2013-03-20
          • 2018-02-22
          • 1970-01-01
          • 2017-05-30
          • 2020-06-08
          • 2019-01-08
          • 1970-01-01
          • 1970-01-01
          • 2018-06-25
          相关资源
          最近更新 更多