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\n", 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\n", 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]]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM