7天玩转 Golang 标准库之 sort

简介: 7天玩转 Golang 标准库之 sort

数据排序 是编程任务的一个常见部分,而Go标准库的sort包提供了对切片和用户定义集合的排序操作。

1.基础排序:整数、浮点数和字符串

Golang自带了对于整数切片[]int,浮点数切片[]float64以及字符切片[]string的排序:

package main

import (
  "fmt"
  "sort"
)

func main() {
  ints := []int{44, 67, 3, 17, 89, 10, 23, 45, 67, -5, 89}
  sort.Ints(ints)
  fmt.Println(ints)

  floats := []float64{4.2, 5.7, 9.8, 1.56, 3.3}
  sort.Float64s(floats)
  fmt.Println(floats)

  strs := []string{"peach", "kiwi", "apple", "banana"}
  sort.Strings(strs)
  fmt.Println(strs)
}

2.自定义类型的排序

sort库允许你对自定义数据类型进行排序,但需要实现sort接口,这意味着你需要为类型定义Len(), Less()Swap()这三个方法。比如,我们对以下struct类型数据进行排序:

type Person struct {
  Name string
  Age  int
}

// 类型别名,方便接下来的定义
type PersonSlice []Person

// 实现sort.Interface接口
func (a PersonSlice) Len() int           { return len(a) }
func (a PersonSlice) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a PersonSlice) Less(i, j int) bool { return a[i].Age < a[j].Age }  //根据Age排序

func main() {
  ps := []Person{
    {"Alice", 23},
    {"Bob", 25},
    {"Mike", 22},
    {"John", 26},
    {"Lucy", 21},
  }

  sort.Sort(PersonSlice(ps))

  for _, v := range ps {
    fmt.Println(v.Name, ":", v.Age)
  }
}

非常高兴你对这个主题有深入的兴趣。在Golang的sort库中,除了以上的基础排序和自定义类型排序,你还可以针对自定义类型进行多字段排序,以及使用sort.Search进行查找。以下是进一步的深入示例:


3.多字段排序

在自定义类型排序的基础上,你可能会遇到需要按照多个字段进行排序的场景。例如,当Person的Age相同时,我们希望能按照Name的字典顺序进行排序。这就需要我们在Less方法中增加额外的判断。

type Person struct {
  Name string
  Age  int
}

type PersonSlice []Person

func (a PersonSlice) Len() int { return len(a) }
func (a PersonSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a PersonSlice) Less(i, j int) bool {
  if a[i].Age == a[j].Age {
    return a[i].Name < a[j].Name  //Age相等时按Name排序
  }
  return a[i].Age < a[j].Age
}

func main() {
  ps := []Person{
    {"Alice", 23},
    {"Bob", 24},
    {"Charlie", 23},
    {"Dave", 24},
  }

  sort.Sort(PersonSlice(ps))

  for _, v := range ps {
    fmt.Println(v.Name, ":", v.Age)
  }
}

4.使用sort.Search进行查找

使用sort的另一个重要场景是进行有序切片的搜索。sort.Search函数可以运行一个自定义的查找函数,返回满足该函数的第一个元素的索引。

func main() {
  ints := []int{1, 3, 5, 7, 9, 11, 13, 15}

  // 搜索大于等于10的第一个元素的索引
  idx := sort.Search(len(ints), func(i int) bool { return ints[i] >= 10 })
  fmt.Println(idx)  // 输出: 5
}

可以看到Go的sort库提供的排序和查找功能是非常强大和灵活的,无论是哪种场景,它都可以提供有效的解决方案。

结语

无论对于基本数据类型还是自定义类型,Go的sort库都能为你提供强大的排序功能,理解并熟练使用sort库将大大提高你的编程效率。


相关文章
|
2月前
|
测试技术 Go 开发者
go-carbon v2.3.8 发布,轻量级、语义化、对开发者友好的 golang 时间处理库
carbon 是一个轻量级、语义化、对开发者友好的 golang 时间处理库,支持链式调用。
36 0
|
3天前
|
SQL NoSQL Go
技术经验分享:Golang标准库:errors包应用
技术经验分享:Golang标准库:errors包应用
|
2月前
|
Go
Golang标准库sync的使用
Golang标准库sync的使用
25 2
|
2月前
|
存储 网络协议 Go
7天玩转 Golang 标准库之 http/net
7天玩转 Golang 标准库之 http/net
29 2
|
2月前
|
Go 开发工具 git
7天玩转 Golang 标准库之 flag
7天玩转 Golang 标准库之 flag
19 2
|
2月前
|
Shell Go API
7天玩转 Golang 标准库之 os
7天玩转 Golang 标准库之 os
27 1
|
2月前
|
运维 监控 Go
Golang深入浅出之-Go语言中的日志记录:log与logrus库
【4月更文挑战第27天】本文比较了Go语言中标准库`log`与第三方库`logrus`的日志功能。`log`简单但不支持日志级别配置和多样化格式,而`logrus`提供更丰富的功能,如日志级别控制、自定义格式和钩子。文章指出了使用`logrus`时可能遇到的问题,如全局logger滥用、日志级别设置不当和过度依赖字段,并给出了避免错误的建议,强调理解日志级别、合理利用结构化日志、模块化日志管理和定期审查日志配置的重要性。通过这些实践,开发者能提高应用监控和故障排查能力。
116 1
|
2月前
|
中间件 Go API
Golang深入浅出之-Go语言标准库net/http:构建Web服务器
【4月更文挑战第25天】Go语言的`net/http`包是构建高性能Web服务器的核心,提供创建服务器和发起请求的功能。本文讨论了使用中的常见问题和解决方案,包括:使用第三方路由库改进路由设计、引入中间件处理通用逻辑、设置合适的超时和连接管理以防止资源泄露。通过基础服务器和中间件的代码示例,展示了如何有效运用`net/http`包。掌握这些最佳实践,有助于开发出高效、易维护的Web服务。
51 1
|
2月前
|
安全 Go
Golang深入浅出之-Go语言标准库中的文件读写:io/ioutil包
【4月更文挑战第27天】Go语言的`io/ioutil`包提供简单文件读写,适合小文件操作。本文聚焦`ReadFile`和`WriteFile`函数,讨论错误处理、文件权限、大文件处理和编码问题。避免错误的关键在于检查错误、设置合适权限、采用流式读写及处理编码。遵循这些最佳实践能提升代码稳定性。
31 0
|
2月前
|
Java Go C++
Golang每日一练(leetDay0111) 摆动排序II\I Wiggle Sort
Golang每日一练(leetDay0111) 摆动排序II\I Wiggle Sort
32 0
Golang每日一练(leetDay0111) 摆动排序II\I Wiggle Sort