Go语言的map以及sort

本文介绍了一个Go语言中Map使用的实例,演示了如何创建、插入、删除Map元素,以及如何进行Map的反转和排序输出等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过这个例子了解map的使用。


Go语言程序:

// map project main.go
package main

import (
	"fmt"
	"sort"
)

func main() {

	var countryCapitalMap map[string]string
	/* 创建集合 */
	countryCapitalMap = make(map[string]string)

	/* map 插入 key-value 对,各个国家对应的首都 */
	countryCapitalMap["France"] = "Paris"
	countryCapitalMap["Italy"] = "Rome"
	countryCapitalMap["Japan"] = "Tokyo"
	countryCapitalMap["India"] = "New Delhi"
	countryCapitalMap["China"] = "Beijing"

	fmt.Println("Original:")
	/* 使用 key 输出 map 值 */
	for country := range countryCapitalMap {
		fmt.Println("Capital of", country, "is", countryCapitalMap[country])
	}
	fmt.Println("")

	/* map 删除 key-value 对 */
	delete(countryCapitalMap, "India")
	fmt.Println("After deletion:")
	/* 使用 key 输出 map 值 */
	for country := range countryCapitalMap {
		fmt.Println("Capital of", country, "is", countryCapitalMap[country])
	}
	fmt.Println("")

	/* 映射反转 */
	capitalCountryMap := make(map[string]string, len(countryCapitalMap))
	for country, capital := range countryCapitalMap {
		capitalCountryMap[capital] = country
	}
	fmt.Println("After the reversal:")
	for capital := range capitalCountryMap {
		fmt.Println("Country of", capital, "is", capitalCountryMap[capital])
	}
	fmt.Println("")

	/* 查看元素在集合中是否存在 */
	captial, ok := countryCapitalMap["United States"]
	/* 如果 ok 是 true, 则存在,否则不存在 */
	if ok {
		fmt.Println("Capital of United States is", captial)
	} else {
		fmt.Println("Capital of United States is not present")
	}
	fmt.Println("")

	/* 排序输出 */
	var keys []string
	for k := range countryCapitalMap {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		fmt.Println("Key:", k, "Value:", countryCapitalMap[k])
	}
}
 

程序运行结果:

Original:
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi
Capital of China is Beijing

After deletion:
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of China is Beijing

After the reversal:
Country of Paris is France
Country of Rome is Italy
Country of Tokyo is Japan
Country of Beijing is China

Capital of United States is not present

Key: China Value: Beijing
Key: France Value: Paris
Key: Italy Value: Rome
Key: Japan Value: Tokyo

程序说明:

1.map似乎可以直接使用

2.排序可以使用sort包

3.map是无序的需要另外定义一个数组来排序


参考链接:

1.Ubuntu安装Go语言环境

2.Ubuntu构筑LiteIDE的Go语言开发环境



转载于:https://www.cnblogs.com/tigerisland/p/7563558.html

<think>我们正在讨论Go语言sort.SortFunc的使用。根据引用[2],我们知道sort包中的Sort方法底层使用快速排序算法,但要求我们实现Interface接口。然而,用户的问题是关于sort.SortFunc的,这是Go 1.8版本引入的一个新函数,它允许我们使用一个比较函数来排序,而无需实现完整的sort.Interface。 sort.SortFunc函数的签名如下(以Go 1.18及以上版本为例,因为Go 1.18引入了泛型): ```go func SortFunc[T any](slice []T, cmp func(a, b T) int) ``` 其中,`T`是切片元素的类型,`cmp`是一个比较函数,它接受两个类型为`T`的参数,并返回一个整数: - 如果`a < b`,则返回负数 - 如果`a == b`,则返回0 - 如果`a > b`,则返回正数 这种设计使得自定义排序更加简洁,无需定义新类型并实现Len、Less、Swap三个方法。 下面我们通过一个例子来演示如何使用sort.SortFunc。 假设我们有一个结构体Person,我们想根据Age字段进行排序: ```go package main import ( "fmt" "slices" // 注意:在Go 1.21之前,sort.SortFunc在sort包中;Go 1.21开始,推荐使用slices.SortFunc ) type Person struct { Name string Age int } func main() { people := []Person{ {"Alice", 25}, {"Bob", 20}, {"Charlie", 30}, } // 使用sort.SortFunc(在Go 1.21之前,使用sort.SortFunc) // 注意:在Go 1.21中,sort包不再有SortFunc,而是移到了slices包中,并且函数名为SortFunc(或Sort) // 这里我们使用slices.SortFunc,因为从Go 1.21开始,官方推荐使用slices包进行切片排序 // 如果你的Go版本是1.18到1.20,可以使用sort.SortFunc(但注意,sort.SortFunc在sort包中,且需要指定类型参数) // 对于Go 1.18-1.20: // sort.SortFunc(people, func(a, b Person) int { // return a.Age - b.Age // 按年龄升序 // }) // 对于Go 1.21+: slices.SortFunc(people, func(a, b Person) int { return a.Age - b.Age }) fmt.Println(people) } ``` 注意:在Go 1.21中,标准库引入了新的slices包,其中包含了很多针对切片的操作,包括排序。因此,对于Go 1.21及以上版本,推荐使用`slices.SortFunc`。同时,为了确保代码的兼容性,我们需要根据使用的Go版本选择不同的包。 另外,比较函数返回`a.Age-b.Age`可以实现升序排序。如果想要降序排序,可以返回`b.Age - a.Age`。 但是,请注意:使用减法来比较整数可能会在整数溢出时出现问题(例如,当a.Age是一个很大的正数,而b.Age是一个很大的负数时,减法可能会溢出)。为了避免这种情况,我们可以显式地比较: ```go // 升序 if a.Age < b.Age { return -1 } else if a.Age > b.Age { return 1 } return 0 ``` 或者更简洁地使用: ```go return cmp.Compare(a.Age, b.Age) ``` 这里,`cmp`是Go 1.21中新增的包,它提供了比较函数。所以我们可以这样写: ```go import "cmp" // ... slices.SortFunc(people, func(a, b Person) int { return cmp.Compare(a.Age, b.Age) }) ``` 这样写更安全,而且可读性更高。 总结一下,使用sort.SortFunc(或slices.SortFunc)的步骤: 1. 确定要排序的切片类型。 2. 定义一个比较函数,该函数接收两个相同类型的参数,并返回一个整数表示它们的相对顺序。 3. 调用SortFunc函数,传入切片和比较函数。 现在,让我们生成相关问题。</think>在 Go 语言中,`sort.SortFunc`(Go 1.21+ 推荐使用 `slices.SortFunc`)允许通过自定义比较函数实现灵活排序,无需实现完整接口。以下是详细使用方法: ### 核心步骤 1. **定义比较函数** 函数签名:`func(a, b T) int` - 返回负数:`a` 排在 `b` 前 - 返回 `0`:相等 - 返回正数:`a` 排在 `b` 后 2. **调用排序方法** - Go 1.21+:使用 `slices.SortFunc` - Go 1.18-1.20:使用 `sort.SortFunc` ### 完整示例(按结构体字段排序) ```go package main import ( "fmt" "slices" // Go 1.21+ ) type Person struct { Name string Age int } func main() { people := []Person{ {"Alice", 25}, {"Bob", 20}, {"Charlie", 30}, } // 按年龄升序 slices.SortFunc(people, func(a, b Person) int { return a.Age - b.Age // 升序:a.Age < b.Age 时返回负数 }) fmt.Println("升序:", people) // [{Bob 20} {Alice 25} {Charlie 30}] // 按姓名降序 slices.SortFunc(people, func(a, b Person) int { return -1 * strings.Compare(a.Name, b.Name) // 降序:反转比较结果 }) fmt.Println("姓名降序:", people) // [{Charlie 30} {Bob 20} {Alice 25}] } ``` ### 关键技巧 1. **多字段排序** ```go slices.SortFunc(people, func(a, b Person) int { if a.Age != b.Age { return a.Age - b.Age // 优先按年龄 } return strings.Compare(a.Name, b.Name) // 年龄相同按姓名 }) ``` 2. **使用 `cmp` 包简化(Go 1.21+)** ```go import "cmp" slices.SortFunc(people, func(a, b Person) int { return cmp.Compare(a.Age, b.Age) // 等效于 a.Age - b.Age }) ``` 3. **反向排序** 反转比较结果或使用 `slices.Reverse`: ```go slices.SortFunc(people, func(a, b Person) int { return b.Age - a.Age // 年龄降序 }) // 或 slices.Sort(people) // 先升序 slices.Reverse(people) // 再反转 ``` ### 注意事项 1. Go 1.21 起推荐 `slices.SortFunc`,旧版本用 `sort.SortFunc` 2. 比较函数需满足传递性:若 `a<b` 且 `b<c`,则 `a<c` 3. 对基本类型切片可直接使用 `slices.Sort`: ```go ints := []int{3, 1, 4} slices.Sort(ints) // [1, 3, 4] ``` 通过自定义比较函数,`sort.SortFunc` 提供了比传统 `sort.Interface` 更简洁的排序实现方式[^1][^2]。 --- ### 相关问题 1. **Go 1.21 的 `slices` 包还提供了哪些常用集合操作?** 2. **如何对复杂嵌套结构(如 `map` 的值)进行排序?** 3. **在自定义排序中如何处理空值或特殊边界条件?** 4. **`sort.SortFunc` 与 `sort.Slice` 在性能上有何差异?** [^1]: Gosort 模块提供了对切片和自定义数据结构的排序功能,支持基本类型排序、自定义排序规则。 [^2]: sort.SortFunc 底层使用快速排序算法,通过自定义比较函数实现灵活排序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值