Go学习笔记map部分

map 是一种特殊的数据结构:一种元素对 (pair) 的无序集合,pair 的一个元素是 key,对应的另一个元素是 value,所以这个结构也称为关联数组或字典。这是一种快速寻找值的理想结构:给定 key,对应的 value 可以迅速定位。

声明和初始化方法

声明方法

在声明的时候不需要知道 map 的长度,map 是可以动态增长的。未初始化的 map 的值是 nil。

var map1 map[keytype]valuetype
var map1 map[string]int

key 可以是任意可以用 == 或者 != 操作符比较的类型,比如 string、int、float32(64)。所以数组、切片和结构体不能作为 key (译者注:含有数组切片的结构体不能作为 key,只包含内建类型的 struct 是可以作为 key 的),但是指针和接口类型可以。如果要用结构体作为 key 可以提供 Key() 和 Hash() 方法,这样可以通过结构体的域计算出唯一的数字或者字符串的 key。

初始化方法
var map1 = make(map[keytype]valuetype)
map1 := make(map[keytype]valuetype)
map1 :=map[int]string{1:"asd",2:"adas",3:"dad"}

可以使用make的第三个参数capacity定义容量

map2 := make(map[string]float32, 100)

测试键值对是否存在及删除元素

测试存在

使用下面的方法可以判断,对应的键值对是否存在

val1, isPresent = map1[key1]

isPresent 返回一个 bool 值:如果 key1 存在于 map1,val1 就是 key1 对应的 value 值,并且 isPresent 为 true;如果 key1 不存在,val1 就是一个空值,并且 isPresent 会返回 false。

删除元素

直接 delete(map1, key1) 就可以。
如果 key1 不存在,该操作不会产生错误。

map的for range操作

for key, value := range map1 {
	...
}

注意 map 不是按照 key 的顺序排列的,也不是按照 value 的序排列的。

译者注:map 的本质是散列表,而 map 的增长扩容会导致重新进行散列,这就可能使 map 的遍历结果在扩容前后变得不可靠,Go 设计者为了让大家不依赖遍历的顺序,每次遍历的起点–即起始 bucket 的位置不一样,即不让遍历都从某个固定的 bucket0 开始,所以即使未扩容时我们遍历出来的 map 也总是无序的。

练习 8.1 map_days.go

创建一个 map 来保存每周 7 天的名字,将它们打印出来并且测试是否存在 “Tuesday” 和 “Hollyday”。

package main

import "fmt"

func main() {
	week := map[string]int{"Monday": 1, "Tuesday": 2, "Wednesday": 3, "Thursday": 4, "Friday": 5, "Saturday": 6, "Sunday": 7}
	fmt.Print(week, "\n")
	for key, value := range week {
		if key == "Tuesday" {
			fmt.Print(value, "Tuesday存在\n")
		} else if key == "Hollyday" {
			fmt.Print(value, "Hollyday存在\n")
		} else {
			fmt.Print("不存在\n")
		}
	}
}

结果:
在这里插入图片描述

map的切片

假设我们想获取一个 map 类型的切片,我们必须使用两次 make() 函数,第一次分配切片,第二次分配切片中每个 map 元素

items := make([]map[int]int, 5)
for i:= range items {
	items[i] = make(map[int]int, 1)
	items[i][1] = 2
}

map 的排序

如果你想为 map 排序,需要将 key(或者 value)拷贝到一个切片,再对切片排序

package main

import (
	"fmt"
	"sort"
)

var (
	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}
)

func main() {
	fmt.Println("unsorted:")
	for k, v := range barVal {
		fmt.Printf("Key: %v, Value: %v / ", k, v)
	}
	keys := make([]string, len(barVal))
	i := 0
	for k, _ := range barVal {
		keys[i] = k
		i++
	}
	sort.Strings(keys)
	fmt.Println()
	fmt.Println("sorted:")
	for _, k := range keys {
		fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
	}
}

map键值对调

如果 map 的值类型可以作为 key 且所有的 value 是唯一的,那么通过下面的方法可以简单的做到键值对调

package main
import (
	"fmt"
)

var (
	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}
)

func main() {
	invMap := make(map[int]string, len(barVal))
	for k, v := range barVal {
		invMap[v] = k
	}
	fmt.Println("inverted:")
	for k, v := range invMap {
		fmt.Printf("Key: %v, Value: %v / ", k, v)
	}
}
练习 8.2 map_drinks.go

构造一个将英文饮料名映射为法语(或者任意你的母语)的集合;先打印所有的饮料,然后打印原名和翻译后的名字。接下来按照英文名排序后再打印出来。

package main

import (
	"fmt"
	"sort"
)

func main() {
	drink := map[string]string{"可乐": "cola", "雪碧": "xuebi", "红牛": "redmer", "脉动": "maidong", "冰红茶": "blacktea"}
	for _, value := range drink {
		fmt.Print(value, "\n")
	}
	for key, value := range drink {
		fmt.Print(key, ":", value, "\n")
	}
	sl := make([]string, len(drink))
	i := 0
	for _, value := range drink {
		sl[i] = value
		i++
	}
	sort.Strings(sl)
	for _, value := range sl {
		fmt.Print(value, "\n")
	}
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值