巧用 Go Map 特性对数组或切片去重
【摘要】 本文介绍了如何利用 Go 的复合数据类型 Map 的特性对数组或切片进行去重。值得注意的一个地方是,在使用 Map 构建 Set 时,Value 的数据类型指定为 struct{},原因是后面在添加键值对的时候,指定的 Value 为空结构体 strcut{}{},空结构体不占用内存空间。
作者:陈明勇
专注分享后端知识,如果文章对您有帮助,欢迎点赞收藏加关注,一起学习,一起进步!
前言
在其他语言里(如 Java
)使用过 Set
集合的小伙伴都知道,它的一个特点就是集合里的元素是不重复的。在一些需要去重场景中,我们可以使用 Set
这种数据结构去存储数据,达到去重的目的。而在 Go
语言里面,是没有 Set
这种数据类型的。如果我们想利用无重复元素的数据结构对数组或切片去重,可以使用 Go
的复合数据类型 Map
去构建 Set
集合,对数组或切片进行去重。因为 Map
中的 key
是唯一的,如果不了解 Map
的小伙伴,可以看看我的这篇文章 一文了解 Go 的复合数据类型(数组、Slice 切片、Map)
。
使用 Map 构建 Set
type MySet map[any]struct{}
定义一个自定义类型 MySet
,具有 map[any]strcut{}
的特性。
map
的key
是any
类型,任何类型都可以当做map
的key
;map
的value
是struct{}
类型,为什么会用结构体类型?是因为后面添加k-v
键值对时,指定的value
为 空结构体strcut{}{}
,fmt.Println(unsafe.Sizeof(struct{}{})) // 0
空结构体是不占用内存空间的。
对数组或切片去重
import "fmt"
type MySet map[any]struct{}
func main() {
s1 := []int{1, 1, 2, 3}
fmt.Println(duplicateRemoving(s1)) // [1 2 3]
s2 := []string{"a", "b", "c", "a"}
fmt.Println(duplicateRemoving(s2)) // [a b c]
}
func duplicateRemoving[T any](s []T) []T {
res := make([]T, 0, len(s))
mySet := make(MySet)
for _, t := range s {
if _, ok := mySet[t]; !ok {
res = append(res, t)
mySet[t] = struct{}{}
}
}
return res
}
核心思路
- 定义一个新的切片
res
,为去重后的切片;定义一个MySet
类型的变量mySet
,用于判断元素是否重复; - 遍历原切片
s
,首先判断mySet
里是否存在以切片s
的元素t
为key
的键值对,如果不存在,往新切片res
添加元素t
,往mySet
里添加键值对t → struct{}{}
,否则说明元素重复,不做添加操作; - 返回去重后的新切片。
小结
本文介绍了如何利用 Go
的复合数据类型 Map
的特性对数组或切片进行去重。值得注意的一个地方是,在使用 Map
构建 Set
时,Value
的数据类型指定为 struct{}
,原因是后面在添加键值对的时候,指定的 Value
为空结构体 strcut{}{}
,空结构体不占用内存空间。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)