zoukankan      html  css  js  c++  java
  • 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())
    }
    
  • 相关阅读:
    C#与面向对象编程语言
    Windows Communication Fundation(WCF)的安装和一些疑惑
    Windows Communication Foundation入门(Part Two)
    Design & Pattern团队公告
    解决方案、项目、程序集、命名空间
    你注意到了吗?
    我的个人主页
    PetShop与设计
    CKEditor/CKFinder升级心得
    [转贴]基于UDP、TCP协议的C#网络编程之一
  • 原文地址:https://www.cnblogs.com/52php/p/7428854.html
Copyright © 2011-2022 走看看