博客 / 詳情

返回

Golang基礎筆記四之map

本文首發於公眾號:Hunter後端

原文鏈接:Golang基礎筆記四之map

這一篇筆記介紹 Golang 裏 map 相關的內容,以下是本篇筆記目錄:

  1. map 的概念及其聲明與初始化
  2. map 的增刪改查
  3. map 的遍歷

1、map 的概念及其聲明與初始化

map,即映射,是 Golang 裏無序鍵值對的集合。

以下是創建 map 的兩種方式。

1. 使用 make 的方式創建

    m := make(map[string]int)
    m["Hunter"] = 1
    fmt.Println(m)

使用 make 進行初始化的時候,也可以指定其容量大小:

m := make(map[string]int, 4)

2. 映射字面量初始化

    m := map[string]int{
        "Hunter": 1,
    }
    fmt.Println(m)

注意:當我們聲明一個 map 之後,它的值是 nil,即 Go 裏的空值,一定要對其初始化之後才可向其中添加元素。

比如下面的操作會引發錯誤:

    var m map[string]int
    m["Hunter"] = 1 // 錯誤,需要初始化

下面的操作才是正確的操作:

    var m map[string]int
    m = make(map[string]int)
    m["Hunter"] = 1
    fmt.Println(m)

介紹這個操作是因為在多重 map 或者説嵌套的 map 裏很容易忘記這個操作。

3. 多重 map

比如我們想創建一個多重 map,其示例數據如下:

{
    "張三": {
        "number": "00001",
        "email": "123@qq.com"
    },
    "李四": {
        "number": "00002",
        "email": "456@qq.com"
    }
}

我們可以如此操作:

var m = make(map[string]map[string]string)
m["張三"] = make(map[string]string)
m["張三"]["number"] = "00001"
m["張三"]["email"] = "123@qq.com"

m["李四"] = make(map[string]string)
m["李四"]["number"] = "00002"
m["李四"]["email"] = "456@qq.com"

fmt.Println(m)

2、map 的增刪改查

我們先定義一個 map 如下:

m := make(map[string]int)

1. 增

如果想要往其中增加一個 key-value,可以直接添加:

m["a"] = 1

2. 改

如果想要修改其中的值,跟增加一個元素的操作一樣:

m["a"] = 2

3. 查

如果想查詢某個 key 對應的 value,可以如下操作:

value := m["a"]
fmt.Println(value)

而如果這個 key 是不存在的,這個操作也不會報錯,而是會返回對應 value 類型的零值。

所謂零值,就是變量被聲明但卻未顯式初始化時,系統自動賦予該變量的默認值,比如整型變量的零值是 0,布爾型的零值是 false,字符串的零值是空字符串 "" 等。

比如這裏我們獲取 key = "b",其返回的結果就是 int 型的零值 0:

value := m["b"]
fmt.Println(value) // 0

這裏如果我們要區分 map 中這個 key 對應的 value 值是 0,還是這個 key 不存在於 map 中的話,有時候會不太好判斷,那麼我們可以用另一種方式來操作:

value, exists := m["b"]
if exists {
    fmt.Printf("m 存在 key 為 b 的數據,value 為 %d", value)
} else {
    fmt.Printf("m 不存在 key 為 b 的數據")
}

4. 刪

如果想要刪除 map 中的某個 key,可以如下操作:

delete(m, "a")

這裏,即便是對應的 key 不存在於 map 中,這個操作也不會報錯。

5. 清空 map

如果想要清空一個 map,可以使用 for 循環對 map 的 key 挨個刪除:

m := map[string]int{
    "a": 1,
    "b": 2,
    "c": 3,
}
fmt.Println(m)
for key, _ := range m {
    delete(m, key)
}
fmt.Println(m)

另一種更高效的方案就是重新對其初始化操作:

fmt.Println(m)
m = make(map[string]int)
fmt.Println(m)

3、map 的遍歷

我們可以使用 for 循環對 map 進行遍歷操作:

m := map[string]int{
    "a": 1,
    "b": 2,
    "c": 3,
}
for key, value := range m {
    fmt.Printf("Key: %s, Value: %d\n", key, value)
}

1. 按照 key 正序排列遍歷打印

下面這個操作是先將 map 中的 key 做成一個切片,然後對切片進行排序,最後再遍歷切片即可。

注意:這裏需要引入 sort 模塊

m := map[string]int{
    "a": 1,
    "b": 3,
    "c": 2,
}

keyList := make([]string, 0, len(m))

for key, _ := range m {
    keyList = append(keyList, key)
}

sort.Strings(keyList)

for _, key := range keyList {
    fmt.Println(key, m[key])
}

2. 按照 key 倒序排列遍歷打印

同樣,這裏也是將 key 全部取出來,然後倒序操作:

m := map[string]int{
    "a": 1,
    "b": 3,
    "c": 2,
}

keyList := make([]string, 0, len(m))

for key, _ := range m {
    keyList = append(keyList, key)
}

sort.Slice(keyList, func(i, j int) bool {
    return keyList[i] > keyList[j]
})

for _, key := range keyList {
    fmt.Println(key, m[key])
}

3. 按照 value 正序排列遍歷打印

對 value 進行排序,這裏的做法是先定義一個結構體 struct,然後將 map 中的 key-value 賦值到這個 struct,做成一個 struct 切片,然後對結構體切片按 value 進行排序。

這裏結構體的概念會在後面介紹,這裏先直接使用:

m := map[string]int{
    "a": 1,
    "b": 3,
    "c": 2,
}

type kv struct {
    Key   string
    Value int
}

var sortedKV []kv

for k, v := range m {
    sortedKV = append(sortedKV, kv{k, v})
}

sort.Slice(sortedKV, func(i, j int) bool {
    return sortedKV[i].Value < sortedKV[j].Value
})

for _, kv := range sortedKV {
    fmt.Printf("%s: %d\n", kv.Key, kv.Value)
}

4. 按照 value 倒序排列遍歷打印

按照 value 倒序排列的方式與按 value 正序排列的方式類似,只是需要將排序規則改為 > 即可:

m := map[string]int{
    "a": 1,
    "b": 3,
    "c": 2,
}

type kv struct {
    Key   string
    Value int
}

var sortedKV []kv

for k, v := range m {
    sortedKV = append(sortedKV, kv{k, v})
}

sort.Slice(sortedKV, func(i, j int) bool {
    return sortedKV[i].Value > sortedKV[j].Value
})

for _, kv := range sortedKV {
    fmt.Printf("%s: %d\n", kv.Key, kv.Value)
}
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.