Golang 实现 set 集合,变相实现 切片去重、排序 功能
Java 中的集合(set)去重很方便,PHP 中的数组值去重,就更加方便,一个函数搞定:array_unique(),Golang 中就比较苦逼了,官方没有提供对“切片去重”的功能,而项目中,又经常用到这个功能,,我们可以模拟 Java 集合的功能,实现 Golang 版集合的同时,顺便把 去重 和 排序 做了,它的主要实现原理是:利用 map 数据 不允许键重名 的特点
,参考代码如下:
# set_int.go
package utils import ( "sort" "sync" ) // 实现 set 集合,变相实现 切片去重 // by phpgo.cnblogs.com type IntSet struct { m map[int]bool sync.RWMutex } func NewIntSet() *IntSet { return &IntSet{ m: map[int]bool{}, } } func (s *IntSet) Add(items ...int) { s.Lock() defer s.Unlock() if len(items) == 0 { return } for _, item := range items { s.m[item] = true } } func (s *IntSet) Remove(items ...int) { s.Lock() defer s.Unlock() if len(items) == 0 { return } for _, item := range items { delete(s.m, item) } } func (s *IntSet) Has(item int) bool { s.RLock() defer s.RUnlock() _, ok := s.m[item] return ok } func (s *IntSet) Len() int { return len(s.List()) } func (s *IntSet) Clear() { s.Lock() defer s.Unlock() s.m = map[int]bool{} } func (s *IntSet) IsEmpty() bool { if s.Len() == 0 { return true } return false } func (s *IntSet) List() []int { s.RLock() defer s.RUnlock() list := []int{} for item := range s.m { list = append(list, item) } return list } func (s *IntSet) SortList() []int { s.RLock() defer s.RUnlock() list := []int{} for item := range s.m { list = append(list, item) } sort.Ints(list) return list }
# set_string.go
package utils import ( "sort" "sync" ) // 实现 set 集合,变相实现 切片去重 // by 52php.cnblogs.com type StringSet struct { m map[string]bool sync.RWMutex } func NewStringSet() *StringSet { return &StringSet{ m: map[string]bool{}, } } func (s *StringSet) Add(items ...string) { s.Lock() defer s.Unlock() if len(items) == 0 { return } for _, item := range items { s.m[item] = true } } func (s *StringSet) Remove(items ...string) { s.Lock() defer s.Unlock() if len(items) == 0 { return } for _, item := range items { delete(s.m, item) } } func (s *StringSet) Has(item string) bool { s.RLock() defer s.RUnlock() _, ok := s.m[item] return ok } func (s *StringSet) Len() int { return len(s.List()) } func (s *StringSet) Clear() { s.Lock() defer s.Unlock() s.m = map[string]bool{} } func (s *StringSet) IsEmpty() bool { if s.Len() == 0 { return true } return false } func (s *StringSet) List() []string { s.RLock() defer s.RUnlock() list := []string{} for item := range s.m { list = append(list, item) } return list } func (s *StringSet) SortList() []string { s.RLock() defer s.RUnlock() list := []string{} for item := range s.m { list = append(list, item) } sort.Strings(list) return list }
# 应用示例:
package main import ( "utils" "fmt" ) func main() { // int 集合 s := utils.NewIntSet() // 添加数据 s.Add(5, 2, 4, 3, 5, 6, 7) // 去重后的值 fmt.Println(s.List()) // 排序后的值 fmt.Println(s.SortList()) // string 集合 s2 := utils.NewStringSet() // 添加数据 s2.Add("wen", "jian", "bao", "study", "goalng", "bao", "jian") // 去重后的值 fmt.Println(s2.List()) // 排序后的值 fmt.Println(s2.SortList()) }