Golang 高效排序数据详情
作者:frank 发布时间:2023-06-23 08:23:41
1.介绍
在 Golang
语言项目开发中,经常会遇到数据排序问题。Golang 语言标准库 sort 包,为我们提供了数据排序的功能,我们可以直接使用 sort.Sort()
函数进行数据排序,sort.Sort()
函数底层实现是以快排为主,并根据目标数据的具体情况选择不同的排序算法。本文我们介绍 sort 包排序数据的使用方法。
2.切片排序
在 Golang
语言标准库 sort 包中,sort.Sort()
函数用于数据排序,该函数需要一个 interface
类型的入参 sort.Interface
,它包含三个方法,分别是 Len()
,Less()
和 Swap()
。也就是说,如果我们需要使用 sort 包的 Sort 函数进行数据排序,首先入参的数据需要实现这三个方法,或者理解为任意元素类型的切片实现了这三个方法,都可以使用 sort.Sort()
函数排序数据。
sort 包代码:
type Interface interface {
Len() int // 集合中元素的数量
Less(i, j int) bool // 描述元素的顺序
Swap(i, j int) // 交换索引为 i 和 j 的元素
}
func Sort(data Interface)
需要注意的是 sort.Sort()
函数不能保证数据排序是稳定的,如果需要保证数据排序稳定,可以使用 sort.Stable() 函数,“稳定”的含义是原始数据中 a 和 b 的值相等,排序前 a 排在 b 的前面,排序后 a 仍排在 b 的前面。
为了方便读者朋友们理解,我们使用 int 类型的切片作为示例,介绍 sort.Sort()
函数的使用方法,我们定义一个类型 type IntSlice []int
,并且给类型 IntSlice
实现 sort.Interface
接口类型定义的三个方法,然后使用 sort.Sort() 函数排序数据。
示例代码:
package main
import (
"fmt"
"sort"
)
type IntSlice []int
func (s IntSlice) Len() int {
return len(s)
}
func (s IntSlice) Less(i, j int) bool {
return s[i] > s[j]
}
func (s IntSlice) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func main () {
intSlice := IntSlice([]int{1, 3, 5, 7, 9})
fmt.Println(intSlice) // 排序前
sort.Sort(intSlice)
fmt.Println(intSlice) // 排序后
}
输出结构:
[9 7 5 3 1]
[1 3 5 7 9]
读到这里,我相信聪明的读者朋友们已经了解了 sort.Sort()
的使用方式,同时也会产生一个疑问,难道每次使用 sort.Sort() 排序数据,都需要这么麻烦吗?我还不如自己写个遍历排序数据。
是的,当然不用这么麻烦,sort
包已经帮我们封装好了常用函数,我们直接使用就可以了。所以,上面的示例代码可以使用 sort.Ints()
函数排序数据。
示例代码:
func main () {
intSlice := IntSlice([]int{9, 7, 5, 3, 1})
fmt.Println(intSlice) // 排序前
sort.Ints(intSlice)
fmt.Println(intSlice) // 使用 sort.Ints() 排序数据
}
除了 sort.Ints()
,还有 sort.Float64s()
,sort.Strings()
等。
3.自定义集合排序
在 Golang
语言项目开发中,我们经常会使用结构体,如果我们需要排序结构体类型的切片,应该怎么操作呢?
我们可以按照 Part 01
介绍的方式,实现那三个方法,然后调用 sort.Sort()
函数,当然,sort
包也为我们封装了排序结构体类型切片的函数 sort.Slice()
,但是,参数除了需要排序的数据之外,还需要提供一个 Less()
函数类型的参数。
示例代码:
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)
输出结果:
By name: [{Alice 55} {Bob 75} {Gopher 7} {Vera 24}]
By age: [{Gopher 7} {Vera 24} {Alice 55} {Bob 75}]
4总结
本文我们介绍了怎么使用 Golang
语言标准库 sort
包排序数据,需要注意的是,除了本文使用的类型之外,其它任意类型只要实现 sort.Interface
的三个方法,都可以调用 sort.Sort()
函数排序数据。
来源:https://developer.51cto.com/art/202111/689273.htm


猜你喜欢
- 1.在Scrapy工程下新建“middlewares.py”# Importing base64 library because we
- study.py内容如下#!/usr/bin/env python# -*- coding:utf-8 -*-__author__ =
- 保存时代码如下:figure_corp = figure.crop( (32*rate/2, 32*rate/2, 32-32*rate/2
- 前段时间冷空气突袭的时候,据说郊区密云的雪积得挺厚,但北京城内除了飘了一点小雪粒,毫无动静。应该是气温过高所致,我在慈云寺桥附近拍下的照片可
- 长话短说,今天介绍实现此功能的一个方法,需要了解的朋友可以参考下:一、JS 重载页面,本地刷新,返回上一页 代码如下:<a href=
- 用Django开发网站的时候,前端页面内的文本框总是不能被设置为只读,找了一些资料发现可以在form class里面进行设置。方法一:首先在
- ASP中给函数传参确实是个麻烦事,当参数个数特别多的时候(比如有七八个或者更多的参数个数)差不多就要眼冒金星了,一个个的数吧。而且要命的是参
- 本文实例为大家分享了python定时提取实时日志的具体代码,供大家参考,具体内容如下这是一个定时读取 实时日志文件的程序。目标文件是targ
- express中常见的路由规则主要使用的路由规则是get和post两种,即var express = require('expres
- 1、问题:群中有同学贴了如下一段代码,问为何 list 最后打印的是空值? from multiprocessing
- 我的Python环境:3.7在Python类里声明一个装饰器,并在这个类里调用这个装饰器。代码如下:class Test():
- 前言今天学习Django框架,用ajax向后台发送post请求,直接报了403错误,说CSRF验证失败;先前用模板的话都是在里面加一个 {%
- 1、安装依赖包yum -y install gcc-c++ ncurses-devel cmake make perl gcc autoco
- 今天做了一个很简单的小项目,感受到了paramiko模块的强大,也深感自己Linux的功力不行~~一、需求二、简单需求分析及流程图需求很少,
- while语句打印1-20的整数,并且每行打印五个数,为了实现每行5个数,我们使用一个if判断语句来实现,判断当打印出5个数之后,自动换行打
- 这篇博客主要写flatten()作用,及其参数的含义flatten()是对多维数据的降维函数。flatten(),默认缺省参数为0,也就是说
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&
- 前言:之前的文章我们已经开启了爬虫程序的exe之旅,但是我们最终实现的程序存在一个非常大的问题,当进行网络请求的时候,程序卡死,直到数据请求
- 最近在接触一个Django项目,使用的是fbv( function-base views )模式,看起来特别不舒服,项目中有一个模型类117
- python序列类型包括哪三种python序列类型包括:列表、元组、字典列表:有序可变序列创建:userlist = [1,2,3,4,5,