开发者

Go中的字典Map增删改查、排序及其值类型

目录
  • 1、Map 简述
  • 2、Map 声明初始化
    • 2.1 Map 声明
    • 2.1 Map 初始化
  • 3、Map 增删改查 操作
    • 3.1 查找
    • 3.2 插入
    • 3.3 更新
    • 3.4 删除
    • 3.5 长度
  • 4、Map 反转,key-value 对调
    • 5、Map 排序
      • 5.1 按照 键key 进行排序
      • 5.2 按照 值 value 进行排序
    • 6、Map 判断某个键是否存在
      • 7、元素 为 Map 的切片
        • 8、值 为 Slice 的 Map
          • 总结

            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]
            
            http://www.devze.com	// 推荐!可以选择是否在创建时指定该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:b编程客栈eijing 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.python5 长度

            内置函数 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 按照 http://www.devze.com键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.Printl编程客栈n(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]]

            总结

            以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

            0

            上一篇:

            下一篇:

            精彩评论

            暂无评论...
            验证码 换一张
            取 消

            最新开发

            开发排行榜