本文首发于公众号:Hunter后端
原文链接:Golang基础笔记四之map
这一篇笔记介绍 Golang 里 map 相关的内容,以下是本篇笔记目录:
- map 的概念及其声明与初始化
- map 的增删改查
- map 的遍历
1、map 的概念及其声明与初始化
map,即映射,是 Golang 里无序键值对的集合。
以下是创建 map 的两种方式。
1. 使用 make 的方式创建
- m := make(map[string]int)
- m["Hunter"] = 1
- fmt.Println(m)
复制代码 使用 make 进行初始化的时候,也可以指定其容量大小:- m := make(map[string]int, 4)
复制代码 2. 映射字面量初始化
- m := map[string]int{
- "Hunter": 1,
- }
- fmt.Println(m)
复制代码 注意:当我们声明一个 map 之后,它的值是 nil,即 Go 里的空值,一定要对其初始化之后才可向其中添加元素。
比如下面的操作会引发错误:- var m map[string]int
- m["Hunter"] = 1 // 错误,需要初始化
复制代码 下面的操作才是正确的操作:- var m map[string]int
- m = make(map[string]int)
- m["Hunter"] = 1
- fmt.Println(m)
复制代码 介绍这个操作是因为在多重 map 或者说嵌套的 map 里很容易忘记这个操作。
3. 多重 map
比如我们想创建一个多重 map,其示例数据如下:- {
- "张三": {
- "number": "00001",
- "email": "123@qq.com"
- },
- "李四": {
- "number": "00002",
- "email": "456@qq.com"
- }
- }
复制代码 我们可以如此操作:- var m = make(map[string]map[string]string)
- m["张三"] = make(map[string]string)
- m["张三"]["number"] = "00001"
- m["张三"]["email"] = "123@qq.com"
- m["李四"] = make(map[string]string)
- m["李四"]["number"] = "00002"
- m["李四"]["email"] = "456@qq.com"
- fmt.Println(m)
复制代码 2、map 的增删改查
我们先定义一个 map 如下:- m := make(map[string]int)
复制代码 1. 增
如果想要往其中增加一个 key-value,可以直接添加:2. 改
如果想要修改其中的值,跟增加一个元素的操作一样:3. 查
如果想查询某个 key 对应的 value,可以如下操作:- value := m["a"]
- fmt.Println(value)
复制代码 而如果这个 key 是不存在的,这个操作也不会报错,而是会返回对应 value 类型的零值。
所谓零值,就是变量被声明但却未显式初始化时,系统自动赋予该变量的默认值,比如整型变量的零值是 0,布尔型的零值是 false,字符串的零值是空字符串 "" 等。
比如这里我们获取 key = "b",其返回的结果就是 int 型的零值 0:- value := m["b"]
- fmt.Println(value) // 0
复制代码 这里如果我们要区分 map 中这个 key 对应的 value 值是 0,还是这个 key 不存在于 map 中的话,有时候会不太好判断,那么我们可以用另一种方式来操作:- value, exists := m["b"]
- if exists {
- fmt.Printf("m 存在 key 为 b 的数据,value 为 %d", value)
- } else {
- fmt.Printf("m 不存在 key 为 b 的数据")
- }
复制代码 4. 删
如果想要删除 map 中的某个 key,可以如下操作:这里,即便是对应的 key 不存在于 map 中,这个操作也不会报错。
5. 清空 map
如果想要清空一个 map,可以使用 for 循环对 map 的 key 挨个删除:- m := map[string]int{
- "a": 1,
- "b": 2,
- "c": 3,
- }
- fmt.Println(m)
- for key, _ := range m {
- delete(m, key)
- }
- fmt.Println(m)
复制代码 另一种更高效的方案就是重新对其初始化操作:- fmt.Println(m)
- m = make(map[string]int)
- fmt.Println(m)
复制代码 3、map 的遍历
我们可以使用 for 循环对 map 进行遍历操作:- m := map[string]int{
- "a": 1,
- "b": 2,
- "c": 3,
- }
- for key, value := range m {
- fmt.Printf("Key: %s, Value: %d\n", key, value)
- }
复制代码 1. 按照 key 正序排列遍历打印
下面这个操作是先将 map 中的 key 做成一个切片,然后对切片进行排序,最后再遍历切片即可。
注意:这里需要引入 sort 模块- m := map[string]int{
- "a": 1,
- "b": 3,
- "c": 2,
- }
- keyList := make([]string, 0, len(m))
- for key, _ := range m {
- keyList = append(keyList, key)
- }
- sort.Strings(keyList)
- for _, key := range keyList {
- fmt.Println(key, m[key])
- }
复制代码 2. 按照 key 倒序排列遍历打印
同样,这里也是将 key 全部取出来,然后倒序操作:- m := map[string]int{
- "a": 1,
- "b": 3,
- "c": 2,
- }
- keyList := make([]string, 0, len(m))
- for key, _ := range m {
- keyList = append(keyList, key)
- }
- sort.Slice(keyList, func(i, j int) bool {
- return keyList[i] > keyList[j]
- })
- for _, key := range keyList {
- fmt.Println(key, m[key])
- }
复制代码 3. 按照 value 正序排列遍历打印
对 value 进行排序,这里的做法是先定义一个结构体 struct,然后将 map 中的 key-value 赋值到这个 struct,做成一个 struct 切片,然后对结构体切片按 value 进行排序。
这里结构体的概念会在后面介绍,这里先直接使用:- m := map[string]int{
- "a": 1,
- "b": 3,
- "c": 2,
- }
- type kv struct {
- Key string
- Value int
- }
- var sortedKV []kv
- for k, v := range m {
- sortedKV = append(sortedKV, kv{k, v})
- }
- sort.Slice(sortedKV, func(i, j int) bool {
- return sortedKV[i].Value < sortedKV[j].Value
- })
- for _, kv := range sortedKV {
- fmt.Printf("%s: %d\n", kv.Key, kv.Value)
- }
复制代码 4. 按照 value 倒序排列遍历打印
按照 value 倒序排列的方式与按 value 正序排列的方式类似,只是需要将排序规则改为 > 即可:- m := map[string]int{
- "a": 1,
- "b": 3,
- "c": 2,
- }
- type kv struct {
- Key string
- Value int
- }
- var sortedKV []kv
- for k, v := range m {
- sortedKV = append(sortedKV, kv{k, v})
- }
- sort.Slice(sortedKV, func(i, j int) bool {
- return sortedKV[i].Value > sortedKV[j].Value
- })
- for _, kv := range sortedKV {
- fmt.Printf("%s: %d\n", kv.Key, kv.Value)
- }
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |