美文网首页
golang sort.Slice踩坑记录

golang sort.Slice踩坑记录

作者: 夕午wuw | 来源:发表于2022-09-14 17:38 被阅读0次

sort.Slice

sort.Slice是go 1.8版本引入的一个强大排序函数。第一个参数是待排序的任意类型slice;第二个参数是less function,用于比较 i 和 j 对应的元素大小,"较小"的排在前面。注意这里并不真的按照"大小"排序,而是根据less func的定义来决定排序。
func Slice(x any, less func(i, j int) bool)

import (
    "fmt"
    "sort"
)

func main() {
    people := []struct {
        Name string
        Age  int
    }{
        {"Gopher", 7},
        {"Alice", 55},
        {"Vera", 24},
        {"Bob", 75},
    }
    sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
    fmt.Println("By name:", people)

    sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
    fmt.Println("By age:", people)
}

上面这段代码就很好的展示了less function的强大。但同时也需要注意,这里的less function是一个匿名函数,存在的坑接下来我会细说。

匿名函数小坑

假设我们现在要对一个int slice进行排序,小的在前面。很容易写出以下代码:

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

接下来,坑来了。如果我只想对int slice的后半部分进行排序,怎么办?以下代码可行吗:

func sortPartly(nums []int, p int) { // 从p开始排序
     sort.Slice(nums[p:], func(i, j int) bool { // 这里传入的slice不再是完整的nums,而是nums[p:]
         return nums[i] < nums[j]
    })
} // 错误写法

乍一看是可以的,但由于匿名函数的原因,这个写法不可行。在上面那段代码中,需要排序的slice是nums,对于slice中的第i或者第j个元素,less function直接对nums[i]和nums[j]进行比较操作;而在下面那段代码中,需要排序的slice是 nums[:p] ,对于slice中的第i或者第j个元素,less function 仍然是对nums[i]和nums[j] 进行比较操作。实际上,less function应该比较的对象是 nums[i+p]和nums[j+p]
因此,一个正确的部分排序函数应该这样写,对less function的index进行调整:

func sortPartly(nums []int, p int) {
    sort.Slice(nums[p:], func(i, j int) bool {
       return nums[i+p] < nums[j+p]
    })
}

那么,还有另一种优雅一些的写法: 对需要排序的部分新建立一个slice (go语言中的slice都是对一个底层数组的引用),再进行排序。这样就无需调整less function的index。

func sortPartly(nums []int, p int) {
    t := nums[p:]
    sort.Slice(t, func(i, j int) bool {
        return t[i] < t[j]
    })
}

相关文章

  • golang 踩坑记录

    要在golang的不同pakage间引用函数,函数命名必须大写字母开头! 要在golang的不同pakage间引用...

  • golang sort.Slice

    sort.Slice是golang提供的切片排序方法, 其中使用到了反射(reflect)包 使用了闭包 可以参考...

  • 2020-10-19随笔 踩坑0传值

    踩坑:当值传入0时,if条件判断时候会自己转换,记录踩坑。

  • Weex入门踩坑记录

    Weex入门踩坑记录

  • golang sort.Slice用法

    函数签名 demo 本文属于原创,首发于微信公众号【小易哥学呀学】,如需转载请后台留言。

  • golang 配置踩坑

    问题一:将golang工作路径改为D:\GoWorkspace\rulai\后,重新设置GOPATH,执行bee ...

  • Golang踩坑分析

    同步至 https://segmentfault.com/a/1190000020103403 案例1:Gola...

  • windows server上 gorm 连接DB提示 the

    友情提示:window server上很容易就踩坑 1. 背景 语言:golang ORM: gorm 运行环境:...

  • Flutter 开发记录

    Flutter 开发踩坑记录(干货总结)

  • 日常bug记录

    想记录日常碰到的bug,坑踩多了,以后应该碰到坑就比较容易处理或者会少踩坑,后面会慢慢记录bug,截图bug以及最...

网友评论

      本文标题:golang sort.Slice踩坑记录

      本文链接:https://www.haomeiwen.com/subject/woxdortx.html