12《Go语言入门》Map声明、添加删除访问元素、遍历及排序

这是我纯手写的《Go语言入门》,手把手教你入门Go。源码+文章,看了你就会🥴,此处应有掌声👏👏👏。
文章中所有的代码我都放到了github.com/GanZhiXiong/go_learning这个仓库中。

Map声明

  • 声明后添加元素
m := map[string]int{}
m["a"] = 1
  • 声明并初始化
m := map[string]int{"a":1, "b":2, "c":3}
  • make创建
m := make(map[string]int, 10/*Initial Capacity*/)

上一篇文章我们使用make创建了切片,同样make也可以创建Map,不同的是不需要初始化len,原因是Map无法设置元素默认值,而切片可以根据数据的类型设置默认值,比如切片的元素为int类型,默认值则为0.

使用make通过预先设置capacity的方式创建,避免了capacity在自增的过程的分配新的内存空间和内存拷贝,可以减少内存消耗,提高性能。

接下来我代码演示下Map的创建:

func TestInitMap(t *testing.T) {
	m1 := map[int]int{1: 1, 2: 2, 3: 3}
	t.Log(m1, len(m1))

	m2 := map[int]int{}
	t.Log(m2, len(m2))
	m2[0] = 0
	m2[5] = 5
	t.Log(m2, len(m2))

	m3 := make(map[string]string, 10)
	// 不能查看Map的Capacity,否者会报错:Invalid argument for cap
	//t.Log(m3, len(m3), cap(m3))
	t.Log(m3, len(m3))
	m3["a"] = "1"
	m3["b"] = "2"
	m3["c"] = "3"
	m3["d"] = "4"
	t.Log(m3, len(m3))
}

Map添加元素

m[Key] = Value

Map删除元素

delete(m, Key)

例如:

func TestDeleteKey(t *testing.T) {
	m := map[int]int{}
	t.Log(m[1])
	m[2] = 0
	t.Log(m[2])
	printKey3Exists(&m, t)
	m[3] = 0
	printKey3Exists(&m, t)
	delete(m, 3)
	printKey3Exists(&m, t)
}

func printKey3Exists(m *map[int]int, t *testing.T) {
	t.Log(m)

	if v, ok := (*m)[3]; ok {
		t.Logf("key 3's value is %d", v)
	} else {
		t.Log("key 3 is not existing.")
	}
}

Map元素访问

Map元素的访问其实和其他编程语言没什么区别,都是通过Key来得到Value。

t.Log(m3["d"])

不同的是,当访问一个不存在的Key时,Value为类型的默认值,这样虽然可以避免在取一个不存在的Key时,不会出现异常,但是不能知道这个Key到底存不存在。
Go当然考虑到了这一点,即使用10《Go语言入门》循环和条件
中讲过的条件语句特殊写法来实现Key是否存在的判断。

func TestAccessNotExistingKey(t *testing.T) {
	m1 := map[int]int{}
	t.Log(m1[0]) // 0这个key不存在,取int的默认值0为value
	m1[2] = 0
	t.Log(m1[2])

	m2 := map[string]string{}
	t.Log(m2["a"]) // a这个key不存在,取string的默认值空字符串为value
	m2["a"] = "1"
	t.Log(m2["a"])

	// 这样虽然可以避免在取一个不存在的key时,不会出现异常,但是不能知道这个key到底存不存在
	key := 3
	m1[key] = 31
	if v, exists := m1[3]; exists {
		t.Logf("Key %d's value is %d", key, v)
	} else {
		t.Logf("Key %d is not existing", key)
	}
}

Map遍历

和数组、切片的遍历是一样的。
这里我们随便回忆下数组和切片的遍历。
需要注意的是:map底成是通过hash来指定存储位置的,所以遍历出来的元素不是有序的。

func TestTravelMap(t *testing.T) {
	t.Log("Map遍历")
	m3 := make(map[string]string, 10)
	t.Log(reflect.TypeOf(m3))
	m3["a"] = "1"
	m3["b"] = "2"
	m3["c"] = "3"
	m3["d"] = "4"
	t.Log(m3)
	for key, value := range m3 {
		t.Log(key, value)
	}

	t.Log("Array遍历")
	array := [...]string{"a", "b", "c"}
	t.Log(reflect.TypeOf(array))
	for index, element := range array {
		t.Log(index, element)
	}

	t.Log("Slice遍历")
	slice := []string{"a", "b", "c"}
	t.Log(reflect.TypeOf(slice))
	for index, element := range slice {
		t.Log(index, element)
	}
}

Map排序

如何按Key排序Map

我这里写一种方法,通过将Key存储到slice中,然后给slice排序,再遍历slice即可。

func TestSortByKey(t *testing.T) {
	m1 := map[string]int{"aa": 1, "zz": 2, "bb": 3, "yy": 4, "cc": 5, "xx": 6}
	s1 := make([]string, 0, len(m1))
	for k, _ := range m1 {
		s1 = append(s1, k)
	}
	sort.Strings(s1)
	for _, k := range s1 {
		t.Log(k, m1[k])
	}
}

如何按Value排序Map

很容易理解的,直接看代码吧。

func TestSortByValue(t *testing.T) {
	m1 := map[string]int{"aa": 3, "zz": 1, "bb": 5, "yy": 2, "cc": 4, "xx": 6}
	valueSlice := make([]int, 0, len(m1))
	for _, value := range m1 {
		valueSlice = append(valueSlice, value)
	}
	sort.Ints(valueSlice)
	for _, element := range valueSlice {
		for key, value := range m1 {
			if element == value {
				t.Log(key, value)
			}
		}
	}
}

支持🤟

🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟

  • 🎸我会持续编写【软件开发相关】的文章,保持每周至少一篇文章。
  • 🎸如果你也是【软件工程师】,【关注❤️我】,一定会对你有所帮助。
  • 🎸如果这篇文章对你有所帮助,那就麻烦,【点赞👍】
  • 🎸您的支持将给与我更大的动力,谢谢😀。

🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟🤟

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值