1、map 简述
- 哈希表,引用类型,必须初始化才能使用
- 一种无序的基于key-value的数据结构的键值对集合
- 键必须是支持相等运算符 ("=="、"!=") 类型, 如 number、string、 pointer、array、struct,以及对应的 interface
- 值可以是任意类型,没有限制
2、map 声明初始化
2.1 map 声明
声明格式:
var mapname map[keytype] valuetype // 其中:keytype为键类型,valuetype为值类型 // valuetype 不仅可以是标注数据类型,也可以是自定义数据类型
type personinfo struct { id string name string address string } var m1 map[string]int var m2 map[string]personinfo
map类型的变量默认初始值为nil,需要使用make()函数来分配内存。
语法为:
make(map[keytype] valuetype, [cap])
其中cap表示map的容量,该参数是可选参数,但推荐在初始化map的时候就为其指定一个合适的容量。
2.1 map 初始化
2.1.1 声明时填充元素,直接初始化创建
package main import ( "fmt" ) var m1 map[string]float32 = map[string]float32{"go":1, "goland": 8.8} func main() { // 短命名 m2 := map[string]float32 {"go": 1, "python": 6.6} m3 := map[int]struct { name string age int }{ 1: {"user01", 10}, // 可省略元素类型。 2: {"user02", 20}, } fmt.printf("全局变量 map m1 : %v\n", m1) // 全局变量 map m1 : map[go:1 goland:8.8] fmt.printf("局部变量 map m2 : %v\n", m2) // 局部变量 map m2 : map[go:1 python:6.6] fmt.printf("局部变量 map m3 : %v\n", m3) // 局部变量 map m3 : map[1:{user01 10} 2:{user02 20}] }
2.1.2 make () 内置函数 创建
在初始化map的时候就为其指定一个合适的容量,有助于提升性能。
毕竟先申请一大块内存,可避免后续操作时频繁自动扩容。
// 创建了一个键类型为string,值类型为int的map testmap := make(map[string]int) testmap["apollo"] = 11 fmt.printf("局部变量 map testmap : %v\n", testmap) // 局部变量 map testmap : map[apollo:11] // 推荐!可以选择是否在创建时指定该scoremap的初始存储能力,如创建了一个初始存储能力为8的map scoremap := make(map[string]int, 8) scoremap["alex"] = 88 fmt.printf("局部变量 map scoremap : %v\n", scoremap) // 局部变量 map scoremap : map[alex:88]
3、map 增删改查 操作
预先声明初始化字典testmap:
testmap := map[string]string{ "name": "alex", "address": "beijing", "age": "18", }
3.1 查找
在 go 中,要从字典中查找指定键时,会返回两个值:
value, ok := map[key]
- 第一个是真正返回 键key的值value,若key不存在则value为零值 nil
- 第二个则是否找到的标识,为布尔值类型,查找成功,返回
true
,否则返回false
通常以下面的代码形式实现:
// 如果key存在ok为true,value为对应的值;不存在ok为false,value为值类型的零值 value, ok := testmap["name"] if ok{ // 找到 则 ok 为 true fmt.println(value) // alex }else { fmt.println("not found") }
亦可 简写:
if val,ok := testmap["name"]; ok{ fmt.println(val) // alex } if val,ok := testmap["name01"]; !ok{ fmt.println(val) // val为nil }
3.2 插入
直接赋值键值对即可:
testmap["tel"] = "00700" fmt.println(testmap) // map[address:beijing age:18 name:alex tel:00700]
3.3 更新
有则新增,无则改之~
testmap["tel"] = "9888" fmt.println(testmap) // map[address:beijing age:18 name:alex tel:9888]
3.4 删除
go内置函数 delete(),用于删除map容器内的元素,不存在也不会报错!
fmt.println(testmap) // map[address:beijing age:18 name:alex tel:9888] delete(testmap, "job") // 不存在,也不会报错,即不执行任何动作 delete(testmap, "tel") // 键存在,即删除,无返回值 fmt.println(testmap) // map[address:beijing age:18 name:alex]
3.5 长度
内置函数 len() ,求键值对 元素个数
fmt.println(testmap) // map[address:beijing age:18 name:alex] fmt.println(len(testmap)) // 3
4、map 反转,key-value 对调
交换字典的键和值,初始化另外一个map,把key、value互换即可:
fmt.println(testmap) // map[address:beijing age:18 name:alex] revmap := make(map[string]string, 8) for k,v := range testmap{ revmap[v] = k } fmt.println(revmap) // map[18:age alex:name beijing:address]
5、map 排序
go 的字典map是一个无序集合,可以通过分别为字典的键和值创建切片,然后通过对切片进行排序来实现。
值得注意的是:遍历字典也是无序的!
5.1 按照 键key 进行排序
先获取所有key,把key进行排序,再按照排序好的key,进行遍历。
sortmap := map[string]int{"pony": 80, "barry": 100, "eva": 88} sortslice := make([]string, 0) // 初始化 长度 为0 ~~~ for k,_ := range sortmap{ sortslice = append(sortslice, k) } fmt.printf("keyslice:%v\n", sortslice) // keyslice:[pony barry eva] sort.strings(sortslice) // string 类型排序 fmt.printf("sorted keyslice:%v\n", sortslice) // sorted keyslice:[barry eva pony] for _, k := range sortslice{ fmt.println(k, sortmap[k]) // barry 100 // eva 88 // pony 80 }
5.2 按照 值 value 进行排序
先获取所有value,把value进行排序,反转map,再按照排序好的value,进行遍历 反转map。
sortmap := map[string]int{"pony": 80, "barry": 100, "eva": 88} sortslice := make([]int, 0) // 初始化 长度 为0 ~~~ for _, v := range sortmap{ sortslice = append(sortslice, v) } fmt.printf("keyslice:%v\n", sortslice) // keyslice:[100 88 80] sort.ints(sortslice) // int类型 排序 fmt.printf("sorted keyslice:%v\n", sortslice) // sorted keyslice:[80 88 100] // 反转 sortmap revmap := make(map[int]string, 3) for k,v := range sortmap{ revmap[v] = k } // 根据 排序好的值,遍历反转的 map for _, v := range sortslice{ fmt.println(v, revmap[v]) // 80 pony // 88 eva // 100 barry } // 结果:按照键值对应数字大小进行升序排序的结果
6、map 判断某个键是否存在
判断 某个 键是否存在,通常用以下格式:
fmt.println(testmap) // map[address:beijing age:18 name:alex] isexistkey := "key0" if val, ok := testmap[isexistkey]; !ok { fmt.printf("键%v不存在", isexistkey) // 键key0不存在 }else{ fmt.printf("键%v的值为:%v", isexistkey, val) }
7、元素 为 map 的切片
- 没有对切片中的map元素进行初始化,即:[{key01:val01 key02:val02}]
mapslice := make([]map[string]string, 0) // 元素为map的slice,初始长度为0 fmt.println(mapslice) // [] mapslice = append(mapslice, map[string]string{ "name": "alex", "address": "beijing", }) fmt.println(mapslice) // [map[address:beijing name:alex]]
- 对切片中的map元素进行初始化,即:[{key01:val01 key02:valo2} {} {} {}]
var mapslice = make([]map[string]string, 3) for index, value := range mapslice { fmt.printf("index:%d value:%v\n", index, value) } fmt.println("after init") // 对切片中的map元素进行初始化 mapslice[0] = make(map[string]string, 10) mapslice[0]["name"] = "王五" mapslice[0]["password"] = "123456" mapslice[0]["address"] = "红旗大街" 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[]
after init
index:0 value:map[address:红旗大街 name:王五 password:123456]
index:1 value:map[]
index:2 value:map[]
[map[address:红旗大街 name:王五 password:123456] map[] map[]]
8、值 为 slice 的 map
map中值为切片类型,即 { key01: [ elem01 elem02] key02:[]}
slicemap := make(map[string][]string, 3) fmt.println(slicemap) // map[] key01 := "names" value,ok := slicemap[key01] if !ok{ value = make([] string, 0, 2) } value = append(value,"tencent","baidu") slicemap[key01] = value fmt.println(slicemap) // map[names:[tencent baidu]]
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论