11-map

44 阅读2分钟

map(映射)

  • Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现
  • map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用

语法格式: map[KeyType]ValueType

  • KeyType:表示键的类型
  • ValueType:表示键对应的值的类型

map初始化,已经判断是否存在某个键名

package main
import (
    "fmt"
)

func main() {
    // 光声明map类型,但是没有初始化值 a的值就是nil
    var a map[string]int
    fmt.Println(a == nil)// true

    // map的初始化 8是容量
    a = make(map[string]int, 8)
    fmt.Println(a == nil)//false

    // map中添加键值对
    a["小白"] = 100
    a["沫沫"] = 200
    fmt.Println(a)// map[小白:100 沫沫:200]
    fmt.Printf("type:%T\n", a)// type:map[string]int
    fmt.Printf("a:%#v\n", a)// a:map[string]int{"小白":100, "沫沫":200}

    // 声明map的同时完成初始化
    b := map[int]bool{
        1: true,
        2: false,
    }
    fmt.Printf("b:%#v\n", b)// b:map[int]bool{1:true, 2:false}
    fmt.Printf("type:%T\n", b)// type:map[int]bool

    // 报错写法
    // var c map[int]int
    // c[100] = 20//没有初始化报错

    // 判断某个键名key的存在与否
    var scoreMap = make(map[string]int, 8)
    scoreMap["江小北"] = 100
    scoreMap["沫沫"] = 0

    v, ok := scoreMap["人间恶狗"]
    v1, ok1 := scoreMap["沫沫"]
    fmt.Println(v, ok);// 0 false 不存在
    fmt.Println(v1, ok1);// 0 true 存在
}

map的普通遍历 和 删除某个键名

package main
import (
    "fmt"
)

func main() {
    // 判断某个键名key的存在与否
    var scoreMap = make(map[string]int, 8)
    scoreMap["江小北"] = 100
    scoreMap["沫沫"] = 0

    // for-range 遍历
    for key, val := range scoreMap {
        fmt.Println(key, val)// 江小北 100 | 沫沫 0
    }

    // 只遍历key
    for key := range scoreMap {
        fmt.Println(key)// 江小北 沫沫
    }

    // 只遍历值
    for _, val := range scoreMap {
        fmt.Println(val)// 100 0
    }

    // 删除键值对 沫沫
    delete(scoreMap, "沫沫")
    fmt.Println(scoreMap)// map[江小北:100]
}

按某个规则固定顺序遍历map

package main
import (
    "fmt"
    "math/rand"
    "sort"
)

func main() {
    // 判断某个键名key的存在与否
    var scoreMap = make(map[string]int, 50)

    for i := 0; i <= 50; i++ {
        key := fmt.Sprintf("stu%02d", i)
        value := rand.Intn(100)// 0 ~ 99随机整数
        scoreMap[key] = value
    }
    // for-range 遍历
    // for key, val := range scoreMap {
    // 	fmt.Println(key, val)
    // }

    // 按照key从小到大顺序遍历map
    // 1. 先取出所有的key存放到切片中
    keys := make([]string, 0, 100)
    for k := range scoreMap {
        keys = append(keys, k);
    }
    // 2. 对key进行排序
    sort.Strings(keys)//针对字符串类型的进行排序,keys变成有序的切片了
    // 3. 按照排序后的key 对scoreMap排序
    for _, key := range keys {
        fmt.Println(key, scoreMap[key])
    }
}

image.png

元素类型为map的切片

  • 类似js数组里面包了多个对象
package main
import (
    "fmt"
)

func main() {
    // 切片的初始化
    var mapSlice = make([]map[string]int, 8, 8)
    // map的初始化
    mapSlice[0] = make(map[string]int, 8) 
    mapSlice[0]["沫沫"] = 100
    fmt.Println(mapSlice)
    // [map[沫沫:100] map[] map[] map[] map[] map[] map[] map[]]
}

值为切片的map

package main
import (
    "fmt"
)

func main() {
    // map的初始化
    var sliceMap = make(map[string][]int, 8)
    _, ok := sliceMap["沫沫"]
    if ok {
        fmt.Println(sliceMap["沫沫"])
    } else {
        // 切片初始化
        sliceMap["沫沫"] = make([]int, 8, 8)
        sliceMap["沫沫"][0] = 18
        fmt.Println(sliceMap["沫沫"])//[18 0 0 0 0 0 0 0]
    }
}

统计how do you do每个单词出现的字数

package main
import (
    "fmt"
    "strings"
)

func main() {
    // map的初始化
    var sliceMap = make(map[string]int, 10)
    // 1.有哪些单词
    s := "how do you do"
    words := strings.Split(s, " ");
    // 遍历单词做统计
    for _, word := range words {
        v, ok := sliceMap[word]
        if ok {
            // map有这个单词
            sliceMap[word] = v + 1
        } else {
            sliceMap[word] = 1
        }
    }
    fmt.Println(sliceMap)// map[do:2 how:1 you:1]
}