package main
import (
"fmt"
"math/rand"
"sort"
"strings"
"time"
)
/*
map详解
1.map的介绍
2.map的基本使用
3.判断某个键是否存在
4.map的遍历
5.使用delete()函数删除键值对
6.【案例】按照指定顺序遍历map
7.元素为map类型的切片
8.值为切片类型的map
9.练习题
*/
func main() {
/* 1.map的介绍
map是一种【无序】的基于key-value的数据结构,Go语言中的map是引用类型,【必须初始化以后才能使用】。
Go语言中map的定义语法是:map[KeyType]ValueType
其中:
KeyType:表示键的类型
ValueType:表示键对应的值的类型
map类型的变量默认初始值为nil,【需要使用make()函数来分配内存】。语法为:
make:用于slice,map,和channel的初始化。
make(map[KeyType]ValueType,[cap])
其中cap表示map的容量,该参数不是必须的。
注意:获取map的容量不能使用cap, cap返回的是数组和切片分配的空间大小,根本不能用于map,要获取map的容量,可以用len()函数。
2.map基本使用
2.1 map中的数据都是成对出现的,map的基本使用示例代码如下:
scoreMap := make(map[string]int,8)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
fmt.Println(scoreMap) // map[小明:100 张三:90]
fmt.Println(scoreMap["小明"]) // 100
fmt.Printf("scoreMap type is %T\n", scoreMap) // scoreMap type is map[string]int
2.2 map也支持在声明的时候填充元素,例如:
userInfo := map[string]string{
"username":"IT营小王子",
"password":"123456",
}
fmt.Println(userInfo) // map[password:123456 username:IT营小王子]
3.判断map中某个键是否存在
Go 语言中有个判断map中键是否存在的特殊写法,格式是:value,ok := map对象[key]
例子:
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
// 如果key存在,ok为true,v为对应的值;如果key不存在,ok为false,v为值类型的零值。
v,ok := scoreMap["张三"]
if ok {
fmt.Println(v)
} else {
fmt.Println("查无此人")
}
4.map的遍历
4.1 Go 语言中使用for range 遍历 map
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
scoreMap["娜扎"] = 60
for k,v := range scoreMap {
fmt.Println(k,v)
}
// 执行结果是:
张三 90
小明 100
娜扎 60
4.2 Go语言中只想遍历map的key的时候,可以按照下面的写法;注意:遍历map时的元素顺序与添加键值对的顺序无关。
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
scoreMap["娜扎"] = 60
for k := range scoreMap {
fmt.Println(k)
}
// 执行结果是:
张三
小明
娜扎
5.使用delete()函数删除map中的键值对
使用delete()内建函数从map中删除一组键值对,delete()函数的格式如下:
delete(map对象, key)
其中:
1. map对象:表示要删除键值对的map对象
2. key:表示要删除的键值对的键
示例代码如下:
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
scoreMap["娜扎"] = 60
delete(scoreMap, "小明") // 将 小明:100 从map中删除
for k,v := range scoreMap {
fmt.Println(k,v)
}
// 执行结果是:
张三 90
娜扎 60
6.【案例】按照指定顺序遍历map
rand.Seed(time.Now().UnixNano()) // 初始化随机数种子
相关具体实例参考下面6的代码执行
7. 切片的类型为map类型的切片
相关具体实例参考下面7的代码执行
8. map中值的类型为切片类型的操作
相关具体实例参考下面8的代码执行
*/
// 1.map基本使用
scoreMap := make(map[string]int, 8)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
fmt.Println(scoreMap) // map[小明:100 张三:90]
fmt.Println(scoreMap["小明"]) // 100
fmt.Printf("scoreMap type is %T\n", scoreMap) // scoreMap type is map[string]int
// 2.map也支持在声明的时候填充元素
userInfo := map[string]string{
"username": "IT营小王子",
"password": "123456",
}
fmt.Println(userInfo) // map[password:123456 username:IT营小王子]
// 3. Go 语言中使用for range 遍历 map
scoreMap["娜扎"] = 60
for k, v := range scoreMap {
fmt.Println("遍历key-value的结果:", k, v)
}
// 4. Go语言中只想遍历map的key的时候,可以按照下面的写法;注意:遍历map时的元素顺序与添加键值对的顺序无关。
for k := range scoreMap {
fmt.Println("只遍历key的结果:", k)
}
// 5.使用delete()函数删除键值对
scoreMap2 := make(map[string]int)
scoreMap2["张三"] = 90
scoreMap2["小明"] = 100
scoreMap2["娜扎"] = 60
delete(scoreMap2, "小明") // 将 小明:100 从map中删除
for k, v := range scoreMap2 {
fmt.Println(k, v)
}
/* 执行结果是:
张三 90
娜扎 60
*/
// 6.【案例】按照指定顺序遍历map
rand.Seed(time.Now().UnixNano()) // 初始化随机数种子
var scoreMap3 = make(map[string]int, 200)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("stu%02d", i) // 生成stu开头的字符串
value := rand.Intn(100) // 生成0-99的随机整数
scoreMap3[key] = value
}
fmt.Println("查看scoreMap3的结果: ", scoreMap3)
/* 结果是:
查看scoreMap3的结果: map[stu00:85 stu01:76 stu02:60 stu03:64 stu04:33 stu05:39 stu06:11 stu07:47 stu08:77 stu09:23 stu10:80 stu11:21 stu12:47 stu13:12
stu14:56 stu15:61 stu16:53 stu17:68 stu18:95 stu19:68 stu20:61 stu21:6 stu22:85 stu23:19 stu24:53 stu25:40 stu26:76 stu27:14 stu28:48 stu29:9 stu30:43
stu31:90 stu32:69 stu33:83 stu34:90 stu35:71 stu36:2 stu37:25 stu38:62 stu39:44 stu40:36 stu41:95 stu42:89 stu43:27 stu44:89 stu45:77 stu46:84 stu47:5
7 stu48:75 stu49:92 stu50:98 stu51:88 stu52:89 stu53:70 stu54:50 stu55:83 stu56:64 stu57:25 stu58:6 stu59:11 stu60:83 stu61:19 stu62:92 stu63:51 stu64:
85 stu65:27 stu66:69 stu67:42 stu68:40 stu69:93 stu70:46 stu71:81 stu72:99 stu73:20 stu74:22 stu75:86 stu76:61 stu77:5 stu78:19 stu79:43 stu80:38 stu81
:59 stu82:59 stu83:37 stu84:87 stu85:48 stu86:84 stu87:50 stu88:49 stu89:57 stu90:40 stu91:86 stu92:89 stu93:97 stu94:68 stu95:54 stu96:18 stu97:49 stu
98:62 stu99:86]
*/
// 取出map中的所有key存入切片keys中
var keys = make([]string, 0, 200)
for key := range scoreMap3 {
keys = append(keys, key)
}
fmt.Println("查看切片keys的结果: ", keys)
/* 结果是:
查看切片keys的结果: [stu47 stu70 stu75 stu98 stu01 stu03 stu21 stu25 stu43 stu66 stu10 stu28 stu32 stu37 stu74 stu05 stu33 stu45 stu84 stu85 stu89 stu
97 stu30 stu35 stu58 stu11 stu42 stu88 stu08 stu14 stu02 stu22 stu29 stu76 stu63 stu95 stu18 stu53 stu79 stu99 stu40 stu48 stu50 stu60 stu67 stu15 stu3
6 stu71 stu86 stu17 stu24 stu44 stu09 stu16 stu65 stu72 stu77 stu94 stu00 stu07 stu55 stu78 stu81 stu92 stu54 stu62 stu64 stu39 stu68 stu13 stu19 stu23
stu46 stu61 stu31 stu49 stu90 stu93 stu12 stu26 stu80 stu52 stu83 stu04 stu06 stu27 stu38 stu59 stu91 stu20 stu41 stu73 stu96 stu34 stu51 stu56 stu69
stu87 stu57 stu82]
*/
// 对切片keys进行排序
sort.Strings(keys)
fmt.Println("切片keys排序后的结果是: ", keys)
/* 结果是:
切片keys排序后的结果是: [stu00 stu01 stu02 stu03 stu04 stu05 stu06 stu07 stu08 stu09 stu10 stu11 stu12 stu13 stu14 stu15 stu16 stu17 stu18 stu19 stu20 stu21 stu22 stu23 stu24 stu
25 stu26 stu27 stu28 stu29 stu30 stu31 stu32 stu33 stu34 stu35 stu36 stu37 stu38 stu39 stu40 stu41 stu42 stu43 stu44 stu45 stu46 stu47 stu48 stu49 stu50 stu51 stu52 stu53 stu54 st
u55 stu56 stu57 stu58 stu59 stu60 stu61 stu62 stu63 stu64 stu65 stu66 stu67 stu68 stu69 stu70 stu71 stu72 stu73 stu74 stu75 stu76 stu77 stu78 stu79 stu80 stu81 stu82 stu83 stu84 s
tu85 stu86 stu87 stu88 stu89 stu90 stu91 stu92 stu93 stu94 stu95 stu96 stu97 stu98 stu99]
*/
// 按照排序后的key遍历切片keys
for _, key := range keys {
fmt.Println("看看你的值:", key, scoreMap3[key])
}
/* 结果是:
看看你的值: stu00 3
看看你的值: stu01 53
看看你的值: stu02 42
看看你的值: stu03 82
看看你的值: stu04 29
看看你的值: stu05 92
看看你的值: stu06 52
看看你的值: stu07 87
看看你的值: stu08 76
看看你的值: stu09 27
看看你的值: stu10 38
........省略.......
看看你的值: stu99 11
*/
fmt.Println()
// 7. 切片的类型为map类型的切片
// 下面的代码演示了切片中的元素为map类型时的操作:
var mapSlice = make([]map[string]string, 3)
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
// 结果是:
// index:0 value:map[]
// index:1 value:map[]
// index:2 value:map[]
}
fmt.Println("after init \n")
// 对切片中的map元素进行初始化,设置第一个元素,第一个元素是map类型,KeyType和ValueType都是string,容量设置为10。
// 对上面定义的mapSlice切片第一个元素进行初始化赋值操作,切片中的元素为map类型,map[KeyType]ValueType要保持一致。
mapSlice[0] = make(map[string]string, 10)
mapSlice[0]["name"] = "小王子"
mapSlice[0]["password"] = "123456"
mapSlice[0]["address"] = "海淀区"
mapSlice[0]["age"] = "18岁"
mapSlice[0]["height"] = "173cm"
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
// 结果是:
// index:0 value:map[address:海淀区 age:18岁 height:173cm name:小王子 password:123456]
// index:1 value:map[]
// index:2 value:map[]
}
fmt.Println("查看mapSlice现在的值是:", mapSlice) // 查看mapSlice现在的值是:[map[address:海淀区 age:18岁 height:173cm name:小王子 password:123456] map[] map[]]
fmt.Println()
// 8. map中值的类型为切片类型的操作
var sliceMap = make(map[string][]string, 3)
fmt.Println(sliceMap) // map[]
fmt.Println("after init")
key := "中国"
value, ok := sliceMap[key] // 这一步是将key:=中国,作为sliceMap的key
// map类型的sliceMap中"中国"这个key现在缺少个value值,下面就是给它value值赋值的过程,切片追加元素使用append()函数
fmt.Println(value, ok) // [] false
if !ok {
value = make([]string, 0, 2)
}
value = append(value, "北京", "上海") // 此处为value值赋值
// 给sliceMap中key-value键值对进行赋值操作;将value赋值给对应的key,这里面key=中国,value值等于[北京 上海]
sliceMap[key] = value
fmt.Println("sliceMap最后的结果是: ", sliceMap) // map[中国:[北京 上海]]
// 9. 练习题
// 写一个程序,统计一个字符串中每个单词出现的次数。比如:“how do you do”中次数how=1 do=2 you=1
var wordMap = make(map[string]int)
var str = "how do you she how"
var arrSlice = strings.Split(str, " ") // 根据空格进行切割
fmt.Printf("arrSlice result is :%v ,Type is :%T\n", arrSlice, arrSlice) // arrSlice result is :[how do you she how] ,Type is :[]string
for index, word := range arrSlice {
fmt.Println(index, word)
fmt.Printf("wordMap[%v]默认值是 : %v\n", word, wordMap[word])
fmt.Printf("wordMap[%v]加1运算前的值是 : %v\n", word, wordMap)
fmt.Println("...开始运算...")
// 下面三种写法作用一样
//wordMap[word]++
//wordMap[word] += 1
wordMap[word] = wordMap[word] + 1
fmt.Printf("运算后 wordMap 现在的值是 : %v\n", wordMap)
fmt.Println()
}
fmt.Println("最终结果:", wordMap)
/* 练习题的执行结果是:
arrSlice result is :[how do you she how] ,Type is :[]string
0 how
wordMap[how]默认值是 : 0
wordMap[how]加1运算前的值是 : map[]
...开始运算...
运算后 wordMap 现在的值是 : map[how:1]
1 do
wordMap[do]默认值是 : 0
wordMap[do]加1运算前的值是 : map[how:1]
...开始运算...
运算后 wordMap 现在的值是 : map[do:1 how:1]
2 you
wordMap[you]默认值是 : 0
wordMap[you]加1运算前的值是 : map[do:1 how:1]
...开始运算...
运算后 wordMap 现在的值是 : map[do:1 how:1 you:1]
3 she
wordMap[she]默认值是 : 0
wordMap[she]加1运算前的值是 : map[do:1 how:1 you:1]
...开始运算...
运算后 wordMap 现在的值是 : map[do:1 how:1 she:1 you:1]
4 how
wordMap[how]默认值是 : 1
wordMap[how]加1运算前的值是 : map[do:1 how:1 she:1 you:1]
...开始运算...
运算后 wordMap 现在的值是 : map[do:1 how:2 she:1 you:1]
最终结果: map[do:1 how:2 she:1 you:1]
*/
}