Golang中使用set


兩種 go 實現 set 的思路, 分別是 map 和 bitset。

map 的 key 肯定是唯一的,而這恰好與 set 的特性一致,天然保證 set 中成員的唯一性。而且通過 map 實現 set,在檢查是否存在某個元素時可直接使用 _, ok := m[key] 的語法,效率高。

 

原文鏈接:https://studygolang.com/articles/27476?fr=sidebar

golang-set-A simple set type for the Go language. Also used by Docker, 1Password, Ethereum.
在github上已經有了一個成熟的包,名為golang-set,包中提供了線程安全和非線程安全的set。提供了五個set函數:

// NewSet創建並返回空集的引用,結果集上的操作是線程安全的
func NewSet(s ...interface{}) Set {}
// NewSetFromSlice從現有切片創建並返回集合的引用,結果集上的操作是線程安全的
func NewSetFromSlice(s []interface{}) Set {}
// NewSetWith創建並返回具有給定元素的新集合,結果集上的操作是線程安全的
func NewSetWith(elts ...interface{}) Set {}
// NewThreadUnsafeSet創建並返回對空集的引用,結果集上的操作是非線程安全的
func NewThreadUnsafeSet() Set {}
// NewThreadUnsafeSetFromSlice創建並返回對現有切片中集合的引用,結果集上的操作是非線程安全的。
func NewThreadUnsafeSetFromSlice(s []interface{}) Set {}

 

demo

package main

import (
    "fmt"
    "github.com/deckarep/golang-set"
)

func main() {
    // 默認創建的線程安全的,如果無需線程安全
    // 可以使用 NewThreadUnsafeSet 創建,使用方法都是一樣的。
    s1 := mapset.NewSet(1, 2, 3, 4)
    fmt.Println("s1 contains 3: ", s1.Contains(3))
    fmt.Println("s1 contains 5: ", s1.Contains(5))

    // interface 參數,可以傳遞任意類型
    s1.Add("poloxue")
    fmt.Println("s1 contains poloxue: ", s1.Contains("poloxue"))
    s1.Remove(3)
    fmt.Println("s1 contains 3: ", s1.Contains(3))

    s2 := mapset.NewSet(1, 3, 4, 5)

    // 並集
    fmt.Println(s1.Union(s2))
}

運行結果:

s1 contains 3:  true
s1 contains 5:  false
s1 contains poloxue:  true
s1 contains 3:  false
Set{1, 2, 4, poloxue, 3, 5}

Examples but not exhaustive:

requiredClasses := mapset.NewSet()
requiredClasses.Add("Cooking")
requiredClasses.Add("English")
requiredClasses.Add("Math")
requiredClasses.Add("Biology")

scienceSlice := []interface{}{"Biology", "Chemistry"}
scienceClasses := mapset.NewSetFromSlice(scienceSlice)

electiveClasses := mapset.NewSet()
electiveClasses.Add("Welding")
electiveClasses.Add("Music")
electiveClasses.Add("Automotive")

bonusClasses := mapset.NewSet()
bonusClasses.Add("Go Programming")
bonusClasses.Add("Python Programming")

//Show me all the available classes I can take
allClasses := requiredClasses.Union(scienceClasses).Union(electiveClasses).Union(bonusClasses)
fmt.Println(allClasses) //Set{Cooking, English, Math, Chemistry, Welding, Biology, Music, Automotive, Go Programming, Python Programming}


//Is cooking considered a science class?
fmt.Println(scienceClasses.Contains("Cooking")) //false

//Show me all classes that are not science classes, since I hate science.
fmt.Println(allClasses.Difference(scienceClasses)) //Set{Music, Automotive, Go Programming, Python Programming, Cooking, English, Math, Welding}

//Which science classes are also required classes?
fmt.Println(scienceClasses.Intersect(requiredClasses)) //Set{Biology}

//How many bonus classes do you offer?
fmt.Println(bonusClasses.Cardinality()) //2

//Do you have the following classes? Welding, Automotive and English?
fmt.Println(allClasses.IsSuperset(mapset.NewSetFromSlice([]interface{}{"Welding", "Automotive", "English"}))) //true

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM