Go 1.19.4 Sort排序进阶-Day 12
1. 结构体(切片)排序
结构体返回的是切片。
之前学习了sort.Ints()和sort.Strings(),使用这两个sort库下面的方法,可以对int和strings进行排序。
那如果我要对自定义类型进行排序,怎么办,sort库没提供,怎么办?可以参照sort源码自己写一个。
1.1 sort源码解析
一个需要排序的类型,必须要实现下面接口中的3个方法。
type Interface interface {Len() int // 能取长度,不管有多少元素,也不管是什么数据类型
Less(i, j int) bool // 可以取索引,比较大小
Swap(i, j int) // 交换i与j的索引位置
}对于切片来说,Len和Swap都还好处理,难点就在于Less的比较大小。
任意类型或者自定义的类型,如何使用Less进行大小比较呢?我也没有办法提前知道,这个切片中,到底会存放什么类型的元素。
1.1.1 sort.Ints源码解析
sort.Ints(),ctrl+鼠标左键点击ints,会跳转到sort.go,然后会有这样一行代码:
func Ints(x []int) { Sort(IntSlice(x)) },然后ctrl+鼠标左键点击IntSlice,会跳转到这个代码:
type IntSlice []int
func (x IntSlice) Len() int { return len(x) }
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
调用sort.Ints()时,会调用func Ints(x []int) { Sort(IntSlice(x)) },也就是把我们的需要排序的元素,传到IntSlice(x),作用是把元素先转换为自定义IntSlice类型。
对于Len() int { return len(x) }来说,就是取出元素长度。
Swap(i, j int) { x[i], x[j] = x[j], x[i] },主要作用就是交换2个元素的位置。
Less(i, j int) bool { return x[i] < x[j] },比较元素大小,成立返回true,否则返回flase,并进行位置调整,也就是调用Swap方法,也就是默认升序的情况。
1.1.2 sort.Strings源码解析
sort.Strings()
func Strings(x []string) { Sort(StringSlice(x)) }
type StringSlice []string
func (x StringSlice) Len() int { return len(x) }
func (x StringSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x StringSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
可以看到,int和strings的排序实现逻辑,其实是一样的。
1.2 自定义结构体(切片)排序
package mainimport ("fmt""sort"
)type Runner interface {run()
}type Cat struct {name stringage int
}type CatSlice []Cat // 这里就相当于[]Cat{c1, c2, Cat{"Momo", 99}}func (x CatSlice) Len() int { return len(x) }
func (x CatSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x CatSlice) Less(i, j int) bool { return x[i].age < x[j].age }func main() {var c1 = Cat{"Tom", 20}var c2 = Cat{"Jerry", 18}cats := []Cat{c1, c2, Cat{"Momo", 99}}fmt.Println("排序前:", cats)sort.Sort(CatSlice(cats))fmt.Println("排序后:", cats)
}
=========调试结果=========
排序前: [{Tom 20} {Jerry 18} {Momo 99}]
排序后: [{Jerry 18} {Tom 20} {Momo 99}]
1.3 简化版结构体(切片)排序
sort.Slice(),是专门给切片用的。
package mainimport ("fmt""sort"
)type Runner interface {run()
}type Cat struct {name stringage int
}func main() {var c1 = Cat{"Tom", 20}var c2 = Cat{"Jerry", 18}cats := []Cat{c1, c2, Cat{"Momo", 99}}fmt.Println("排序前:", cats)sort.Slice(cats, func(i, j int) bool {return cats[i].age < cats[j].age})fmt.Println("排序后:", cats)
}
=========调试结果=========
排序前: [{Tom 20} {Jerry 18} {Momo 99}]
排序后: [{Jerry 18} {Tom 20} {Momo 99}]
2. map排序
2.1 key排序
2.1.1 升序
package mainimport ("fmt""sort"
)func main() {m := make(map[int]string)m[2] = "abc"m[1] = "xvz"m[100] = "aaa"fmt.Println(m)keys := make([]int, 0, len(m))for k := range m {keys = append(keys, k)}fmt.Println(keys)sort.Ints(keys)fmt.Println(keys)for _, k := range keys {fmt.Println(k, m[k])}
}
=========调试结果=========
map[1:xvz 2:abc 100:aaa]
[2 1 100]
[1 2 100]
1 xvz
2 abc
100 aaa
2.1.2 降序
package mainimport ("fmt""sort"
)func main() {m := make(map[int]string)m[2] = "abc"m[1] = "xvz"m[100] = "aaa"fmt.Println(m)keys := make([]int, 0, len(m))for k := range m {keys = append(keys, k)}fmt.Println(keys)// sort.Ints(keys)sort.Sort(sort.Reverse(sort.IntSlice(keys))) // 调整这里fmt.Println(keys)for _, k := range keys {fmt.Println(k, m[k])}
}
=========调试结果=========
map[1:xvz 2:abc 100:aaa]
[100 2 1]
[100 2 1]
100 aaa
2 abc
1 xvz
2.2 value排序
2.2.1 升序
package mainimport ("fmt""sort"
)type Entry struct {k intv string
}func main() {m := make(map[int]string)m[2] = "abc"m[1] = "xvz"m[100] = "aaa"fmt.Println(m)entries := make([]Entry, 0, len(m))for k, v := range m {entries = append(entries, Entry{k, v})}fmt.Println(entries)sort.Slice(entries, func(i, j int) bool {return entries[i].v < entries[j].v})fmt.Println(entries)
}
=========调试结果=========
map[1:xvz 2:abc 100:aaa]
[{1 xvz} {100 aaa} {2 abc}]
[{100 aaa} {2 abc} {1 xvz}]
3. 排序总结
排序,只支持线性数据结构,如果是hash类型,一定要先转换成线性数据结构。
相关文章:
Go 1.19.4 Sort排序进阶-Day 12
1. 结构体(切片)排序 结构体返回的是切片。 之前学习了sort.Ints()和sort.Strings(),使用这两个sort库下面的方法,可以对int和strings进行排序。 那如果我要对自定义类型进行排序,怎么办,sort库没提供&…...

python-求距离(赛氪OJ)
[题目描述] 给你一个 1−>n 的排列,现在有一次机会可以交换两个数的位置,求交换后最小值和最大值之间的最大距离是多少?输入格式: 输入共两行。 第一行一个数 n 。 第二行 n 个数表示这个排列。输出格式: 输出一行一…...
《第二十一章 传感器与定位 - 传感器应用》
《第二十一章 传感器与定位 - 传感器应用》 在当今的移动应用开发中,充分利用设备的传感器能够为用户带来更加智能和便捷的体验。本章将重点探讨加速度传感器、方向传感器和光线传感器的应用。 一、传感器应用的重要性 随着智能手机和移动设备的普及,传感…...
Windows系统命令
Windows系统命令 Windows 系统中的命令行工具是指令式编程语言,可以用来执行各种任务、管理文件和目录、监控系统状态等。下面是一个 Windows 命令应用实例: 1. 文件操作 cd:用于改变当前目录。例如,cd Documents 将当前目录更…...

C语言函数递归
前言与概述 本文章将通过多个代码并赋予图示,详细讲解C语言函数递归的定义和函数递归的运算过程。 函数递归定义 程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它…...

【python数据分析11】——Pandas统计分析(分组聚合进行组内计算)
分组聚合进行组内计算 前言1、groupby方法拆分数据2、agg方法聚合数据3、apply方法聚合数据4、transform方法聚合数据5 小案例5.1 按照时间对菜品订单详情表进行拆分5.2 使用agg方法计算5.3 使用apply方法统计单日菜品销售数目 前言 依据某个或者几个字段对数据集进行分组&…...

高性能web服务器
目录 一、简介 (一)nginx-高性能的web服务端 (二)用户访问体验 二、I/O模型 (一)概念 (二)网络I/O模型 (三)阻塞型 I/O 模型 (四…...

微服务案例搭建
目录 一、案例搭建 1.数据库表 2.服务模块 二、具体代码实现如下: (1) 首先是大体框架为: (2)父模块中的pom文件配置 (3)shop_common模块,这个模块里面只需要配置pom.xml,与实体…...

SAP负库存
业务示例 在系统中,对于一些物料而言,不能立即将收到的交货输入为收货。如果要使发货无论如何都是可以过帐的,则需要允许这些物料的负库存。 负库存 发货数量大于预订数量时,过帐该发货就会出现负库存。如果由于组织原因&#…...

集团数字化转型方案(三)
集团数字化转型方案通过系统整合人工智能(AI)、大数据、云计算和物联网(IoT)技术,建立了一个全面智能化的业务管理平台,涵盖从业务流程自动化、数据驱动决策支持,到客户体验优化和供应链管理的各…...
ESP32智能设备:蓝牙音箱、AI语音助手、环境监测与调节以及智能控制,基于BLE与MQTT技术(代码详解)
本文将介绍如何实现一个功能丰富的ESP32项目,集成蓝牙音箱、AI语音助手、智能设备控制器、环境监测与调节等功能。通过本项目,您将学习到硬件设计、嵌入式编程、蓝牙技术、音频处理、人工智能与语音识别、物联网平台、数据分析及用户界面构建等技术。 一…...

web渗透测试 学习导图
web渗透学习路线 前言 一、web渗透测试是什么? Web渗透测试分为白盒测试和黑盒测试,白盒测试是指目标网站的源码等信息的情况下对其渗透,相当于代码分析审计。而黑盒测试则是在对该网站系统信息不知情的情况下渗透,以下所说的Web…...
WordPress禁止后台自定义功能
wordpress后台可以彻底禁止主题的自定义菜单功能,下面这段代码添加到functions.php文件中,后台外观菜单中的”自定义”就会消失不见了。 add_filter(map_meta_cap, function($caps, $cap){if($cap customize){return [do_not_allow];}return $caps; },…...
(六)Flink 窗口计算
窗口(Window)是处理无界流的关键所在。窗口可以将数据流装入大小有限的“桶”中,再对每个“桶”加以处理。 目录 时间概念 窗口类型 窗口划分 窗口的生命周期 Window Assigners 窗口函数 Triggers 窗口触发器 Evictor 数据剔除器 Allowed Lateness 旁路输出 时间…...

SQL 布尔盲注 (injection 第六关)
简介 SQL注入(SQL Injection)是一种常见的网络攻击方式,通过向SQL查询中插入恶意的SQL代码,攻击者可以操控数据库,SQL注入是一种代码注入攻击,其中攻击者将恶意的SQL代码插入到应用程序的输入字段中&am…...

OpenAI 重回巅峰:ChatGPT-4O 最新模型超越谷歌 Gemini 1.5,多项测试夺冠!
谷歌上周发布的Gemini 1.5 Pro模型,在LMSYS办的聊天机器人竞技场Chatbot Arena中获得第一名。但是,OpenAI迅速反应,推出了最新的chatgpt-4o-latest模型,重新夺回了冠军头衔。 chatgpt-4o-latest模型简介 OpenAI最近推出了名为gpt-…...
软件工程(2)面向对象方法:Booch方法与开发实例
Booch方法(Booch Method)是由Grady Booch提出的一种面向对象的软件开发方法。它是一种系统分析与设计的框架,主要用于设计和建模面向对象的系统。Booch方法特别关注对象模型的构建,以及类、对象和它们之间的关系。以下是Booch方法…...
高阶面试-concurrentHashMap的整理
算不上死磕,里面太痛苦了,现在很多位移等操作还看不懂,只是先理清大致思路,面试用 concurrentHashMap的实现原理 为啥会用到?并发安全。之前都用的hashtable实现线程安全的map,但是太过笨重,不…...

VSCode系列 - 如何用VSCode搭建C++高效开发环境(1)
VSCode是笔者用过的最好用的开发工具,没有之一。笔者14年的码龄生涯中,先后用过Eclipse、 IntelliJ IDEA、 WebStorm、 PyCharm、 Visual Studio(2010/2013/2015)、 NetBeans、 Sublime Text等,但自从用VSCode之后,就再没换过其他…...

【人工智能】Python融合机器学习、深度学习和微服务的创新之路
1. 🚀 引言1.1 🚀 人工智能的现状与发展趋势1.2 📜 机器学习、深度学习和神经网络的基本概念1.3 🏆 微服务架构在人工智能中的作用 2. 🔍 机器学习的演变与创新2.1 🌟 机器学习的历史回顾2.2 🧠…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...

npm安装electron下载太慢,导致报错
npm安装electron下载太慢,导致报错 背景 想学习electron框架做个桌面应用,卡在了安装依赖(无语了)。。。一开始以为node版本或者npm版本太低问题,调整版本后还是报错。偶尔执行install命令后,可以开始下载…...