• Go 字典(Map)


       比较熟悉 Python 的对于字典肯定不会陌生,在 Go 中 map 就是 Python 中字典的概念,它的基本格式是

    map[keyType]valueType 。map 的读取和设置和 slice 比较相似,只不过 map 中是通过 key 操作,而 slice

    是通过 index 操作,index 只能是 int 类型,map 的 key 可以是 int 、string等类型。

    字典的赋值方式

    1.先声明再初始化最后赋值

    package main
    
    import "fmt"
    
    func main() {
       // 先声明一个字典,key类型为string value类型为string
       var m1 map[string]string
    
       // 只声明不赋值的map,零值为nil,此时不能给map赋值
       if m1 == nil {
          // 使用 make 函数对map初始化
          m1 = make(map[string]string)
       }
    
    
       if m1 != nil {
           // 输出 map[]
           fmt.Println(m1)
           // 赋值操作
           m1["name"] = "xiaoming"
           fmt.Println(m1)
       }
    } 

    输出结果

    [root@VM_81_181_centos golang]# go run map01.go 
    map[]
    map[name:xiaoming]

    2.使用 make 初始化之后再赋值

    package main
    
    import "fmt"
    
    func main() {
       // 使用 make 直接初始化
       m1 := make(map[string]int)
       m1["age"] = 23
       fmt.Println(m1)
    } 

    输出结果

    [root@VM_81_181_centos golang]# go run map02.go 
    map[age:23]

    3.直接初始化赋值

    package main
    
    import "fmt"
    
    func main() {
       m1 := map[string]string{
          "name":"xiaoming",
          "hobby":"football",
       }
       fmt.Println(m1)
    }

    输出结果

    [root@VM_81_181_centos golang]# go run map03.go 
    map[name:xiaoming hobby:football]
    

     字典的遍历

      字典遍历提供了两种方式,一种是需要携带 value,另一种是只需要 key,需要使用 range 关键字

    package main
    
    import "fmt"
    
    func main() {
       fruits := map[string]int{
          "apple":2,
          "banana":5,
          "orange":8,
       }
    
       // 需要携带 value
       for name,score := range fruits{
           fmt.Println(name, score)
       }
       // 只需要key
       for name := range fruits{
           fmt.Println(name)
       }
    
    }

      输出结果

    [root@VM_81_181_centos golang]# go run map04.go 
    apple 2
    banana 5
    orange 8
    #########
    apple
    banana
    orange

    在 Go 中没有提供类似 keys() 和 values() 这样的方法,如果我们想获取 key 和 value 的列表需要自己循环

    package main
    
    import "fmt"
    
    func main() {
       fruits := map[string]int{
          "apple":2,
          "banana":5,
          "orange":8,
       }
    
       names := make([]string,0,len(fruits))
       scores := make([]int,0,len(fruits))
    
       for name,score := range fruits{
           names = append(names,name)
           scores = append(scores,score)
       }
    
       fmt.Println(names,scores)
    }

    输出结果

    [root@VM_81_181_centos golang]# go run map05.go 
    [apple banana orange] [2 5 8]

    字典的读写

    package main
    
    import "fmt"
    
    func main() {
       fruits := map[string]int {
            "apple": 2,
            "banana": 5,
            "orange": 8,
        }
    
        // 读
        fmt.Println(fruits["apple"])
    
        // 增加或修改
        fruits["pear"] = 9
        fmt.Println(fruits)
    
       // 删除
       delete(fruits, "pear")
    
       fmt.Println(fruits)
    }

    输出结果

    [root@VM_81_181_centos golang]# go run map08.go
    2
    map[banana:5 orange:8 pear:9 apple:2]
    map[apple:2 banana:5 orange:8]

    字典的多态返回值

        在上面的实例中已经可以知道通过 val1 = map1[key1] 的方法获取 key1 对应的值 val1。如果 map 中不存在 key1,

    val1 就是一个值类型的空值。那么,此时就会出现一个问题 key1 是不存在还是 key1 对应的值就是空值?

        下面介绍一种方式判断 map 中 key 是否存在: val1 , isPresent = map1[key1] ,isPresent 返回一个 bool 值:如果

    key1 存在,val1 就是 key1 对应的 value 值,并且 isPresent 为 true;如果 key1 不存在,val1 就是一个空值,并且 isPresent

    返回 false。

         如果只是想判断某个 key 是否存在而不关心它对应的值到底是多少,可以这样做:

    _,ok = map1[key1]// 如果 key1 存在,ok == true 否在 ok == false
    

      或者和 if 混合使用

    if _,ok := map1[key1];ok {
        //....
    }
    

     从 map1 中删除 key1,直接 delete(map1,key1),如果 key1 不存在,该操作也不会报错

    package main
    
    import "fmt"
    
    func main() {
       map1 := make(map[string]int)
    
       map1["New Delhi"] = 55
       map1["Beijing"] = 20
       map1["Washington"] = 25
    
       value,isPresent := map1["Beijing"]
       if isPresent {
          fmt.Printf("The value of "Beijin" in map1 is: %d
    ", value)
       } else {
          fmt.Printf("map1 does not contain Beijing")
       }
    
       // 删除元素
       delete(map1,"Washington")
       value,isPresent = map1["Washington"]
       if isPresent {
           fmt.Printf("The value of "Washington" in map1 is: %d
    ", value)
       } else {
           fmt.Println("map1 does not contain Washington")
       }
    }

    输出结果

    [root@VM_81_181_centos golang]# go run map09.go 
    The value of "Beijin" in map1 is: 20
    map1 does not contain Washington
    [root@VM_81_181_centos golang]# 

    字典的排序

       字典默认是无序的,如果想要为 map 排序,需要将 key (或者value) 拷贝至一个切片中,再对切片排序,然后可以使用

    切片的 for-range 方法打印所有的 key 和 value

    package main
    
    import (
    	"fmt"
    	"sort"
    )
    
    func main() {
    	barVal := map[string]int{
    		"alpha": 34,
    		"bravo": 56,
    		"charlie": 23,
    		"delta": 87,
    		"echo": 56,
    		"foxtrot": 12,
    		"golf": 34,
    		"hotel": 16,
    		"indio": 87,
    		"juliet": 65,
    		"kili": 43,
    		"lima": 98,
    	}
    	fmt.Println("unsorted:")
    	for key,value := range barVal{
    		fmt.Printf("Key: %v, Value: %v / ", key, value)
    	}
    
    	// 创建切片
    	keys := make([]string,len(barVal))
    	i := 0
    	for k,_ := range barVal{
    		keys[i] = k
    		i++
    	}
    
    	sort.Strings(keys)
    
    	fmt.Println("sorted")
    	for _,k := range keys{
    		fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
    	}
    }
    

     输出结果

    unsorted:
    Key: kili, Value: 43 / Key: alpha, Value: 34 / Key: foxtrot, Value: 12 / Key: hotel, Value: 16 / Key: echo, Value: 56 / Key: golf, Value: 34 / Key: indio, Value: 87 / Key: juliet, Value: 65 / Key: lima,
    Value: 98 / Key: bravo, Value: 56 / Key: charlie, Value: 23 / Key: delta, Value: 87 / sorted
    Key: alpha, Value: 34 / Key: bravo, Value: 56 / Key: charlie, Value: 23 / Key: delta, Value: 87 / Key: echo, Value: 56 / Key: foxtrot, Value: 12 / Key: golf, Value: 34 / Key: hotel, Value: 16 / Key: indi
    o, Value: 87 / Key: juliet, Value: 65 / Key: kili, Value: 43 / Key: lima, Value: 98 /
    

    字典的键值对调

       这里的键值对调是指调换 key 和 value ,首先能想到的方法就是构造另一个以原 map 的 key 作为 value,以原 map

    的 value 作为 key 的 map,然后使用 for-range 遍历原 map 并导入新 map

    package main
    
    import "fmt"
    
    func main() {
    	originMap := map[string]int{
    		"a":0,
    		"b":0,
    		"c":2,
    	}
    
    	fmt.Println(originMap)
    
    	newMap := make(map[int]string)
    
    	for key,value := range originMap{
    		newMap[value] = key
    	}
    
    	fmt.Println(newMap)
    }
    

    输出结果

    map[a:0 b:0 c:2]
    map[2:c 0:b]

        看输出结果,会发现上面的代码有一个大问题,如果原 map 的 value 不唯一,就会导致新 map 无法完全包含原 map 的

    键值对,对于这个问题我们可以使用多值 map的方法解决:map[int][]string,用切片作为 map 的值

    package main
    
    import "fmt"
    
    func main() {
    	originMap := map[string]int{
    		"a":0,
    		"b":0,
    		"c":2,
    	}
    
    	fmt.Println(originMap)
    
    	newMap := make(map[int][]string)
    
    	for key,value := range originMap{
    		newMap[value] = append(newMap[value],key)
    	}
    
    	fmt.Println(newMap)
    }

    输出结果

    map[b:0 c:2 a:0]
    map[0:[a b] 2:[c]]
  • 相关阅读:
    字符串_操作
    Error: Cannot find module 'webpack-cli/bin/config-yargs'
    ElementUI-Table 表头无法编辑问题
    ElementUI-Cascader组件同时支持懒加载和选择任意一级 问题踩坑
    vue强制刷新子组件
    footer部分,当页面主题内容不满一屏时,始终位于页面底部
    未知宽高的元素水平垂直居中方法总结
    fix元素居中
    link和@import引入css的区别
    Jquery拓展方法
  • 原文地址:https://www.cnblogs.com/leeyongbard/p/10078723.html
Copyright © 2020-2023  润新知