Basic Usage
package main
import (
"github.com/gogf/gf/v2/container/gset"
"fmt"
)
func main() {
// Create a concurrent safe set object
s := gset.New(true)
// Add an item
s.Add(1)
// Add items in batch
s.Add([]interface{}{1, 2, 3}...)
// Size of the set
fmt.Println(s.Size())
// Check if an item exists in the set
fmt.Println(s.Contains(2))
// Return items as a slice
fmt.Println(s.Slice())
// Remove an item
s.Remove(3)
// Iterate through items
s.Iterator(func(v interface{}) bool {
fmt.Println("Iterator:", v)
return true
})
// Convert the set to a string
fmt.Println(s.String())
// Concurrent safe write lock operation
s.LockFunc(func(m map[interface{}]struct{}) {
m[4] = struct{}{}
})
// Concurrent safe read lock operation
s.RLockFunc(func(m map[interface{}]struct{}) {
fmt.Println(m)
})
// Clear the set
s.Clear()
fmt.Println(s.Size())
}
After execution, the output is:
true
[1 2 3]
Iterator: 1
Iterator: 2
[1 2]
map[1:{} 2:{} 4:{}]
0
Intersection, Difference, Union, Complement
We can achieve intersection, difference, union, and complement using the following methods, and return a new result set,
func (set *Set) Intersect(others ...*Set) (newSet *Set)
func (set *Set) Diff(others ...*Set) (newSet *Set)
func (set *Set) Union(others ...*Set) (newSet *Set)
func (set *Set) Complement(full *Set) (newSet *Set)
Intersect
: Intersection, a set of elements that belong to both set and others.Diff
: Difference, a set of elements that belong to set and not others.Union
: Union, a set of elements that belong to either set or others.Complement
: Complement, (precondition: set should be a subset of full) a set of elements that belong to the universal set full but not to set. If the given full set is not the universal set of set, it returns the difference between full and set.
Through set methods, we can see that intersection, difference, and union methods support multiple set parameters for computation. The following is a simplified example, using only one parameter set.
package main
import (
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/container/gset"
)
func main() {
s1 := gset.NewFrom(g.Slice{1, 2, 3})
s2 := gset.NewFrom(g.Slice{4, 5, 6})
s3 := gset.NewFrom(g.Slice{1, 2, 3, 4, 5, 6, 7})
// Intersection
fmt.Println(s3.Intersect(s1).Slice())
// Difference
fmt.Println(s3.Diff(s1).Slice())
// Union
fmt.Println(s1.Union(s2).Slice())
// Complement
fmt.Println(s1.Complement(s3).Slice())
}
After execution, the output is:
[1 2 3]
[4 5 6 7]
[1 2 3 4 5 6]
[7 4 5 6]
Contains/ContainsI
Inclusion Judgment
package main
import (
"fmt"
"github.com/gogf/gf/v2/container/gset"
)
func main() {
var set gset.StrSet
set.Add("a")
fmt.Println(set.Contains("a"))
fmt.Println(set.Contains("A"))
fmt.Println(set.ContainsI("A"))
// Output:
// true
// false
// true
}
Pop/Pops
Set Item Popping
package main
import (
"fmt"
"github.com/gogf/gf/v2/container/gset"
)
func main() {
var set gset.Set
set.Add(1, 2, 3, 4)
fmt.Println(set.Pop())
fmt.Println(set.Pops(2))
fmt.Println(set.Size())
// May Output:
// 1
// [2 3]
// 1
}
Join
Set Item Concatenation
package main
import (
"fmt"
"github.com/gogf/gf/v2/container/gset"
)
func main() {
var set gset.Set
set.Add("a", "b", "c", "d")
fmt.Println(set.Join(","))
// May Output:
// a,b,c,d
}
IsSubsetOf
Subset Judgment
package main
import (
"fmt"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/frame/g"
)
func main() {
var s1, s2 gset.Set
s1.Add(g.Slice{1, 2, 3}...)
s2.Add(g.Slice{2, 3}...)
fmt.Println(s1.IsSubsetOf(&s2))
fmt.Println(s2.IsSubsetOf(&s1))
// Output:
// false
// true
}
AddIfNotExist*
Conditional Writing
Conditional writing means writing if the specified item does not exist, and returning true
. Otherwise, skipping writing and returning false
. Related methods include:
AddIfNotExist
AddIfNotExistFunc
AddIfNotExistFuncLock
For detailed descriptions of the methods, please refer to the interface documentation or source code comments.
package main
import (
"fmt"
"github.com/gogf/gf/v2/container/gset"
)
func main() {
var set gset.Set
fmt.Println(set.AddIfNotExist(1))
fmt.Println(set.AddIfNotExist(1))
fmt.Println(set.Slice())
// Output:
// true
// false
// [1]
}
Walk
Traverse and Modify
package main
import (
"fmt"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/frame/g"
)
func main() {
var (
set gset.StrSet
names = g.SliceStr{"user", "user_detail"}
prefix = "gf_"
)
set.Add(names...)
// Add prefix for given table names.
set.Walk(func(item string) string {
return prefix + item
})
fmt.Println(set.Slice())
// May Output:
// [gf_user gf_user_detail]
}
JSON
Serialization/Deserialization
All container types under the gset
module implement interfaces for standard library json
data format serialization/deserialization.
Marshal
package main
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/container/gset"
)
func main() {
type Student struct {
Id int
Name string
Scores *gset.IntSet
}
s := Student{
Id: 1,
Name: "john",
Scores: gset.NewIntSetFrom([]int{100, 99, 98}),
}
b, _ := json.Marshal(s)
fmt.Println(string(b))
}
After execution, the terminal output is:
{"Id":1,"Name":"john","Scores":[100,99,98]}
Unmarshal
package main
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/container/gset"
)
func main() {
b := []byte(`{"Id":1,"Name":"john","Scores":[100,99,98]}`)
type Student struct {
Id int
Name string
Scores *gset.IntSet
}
s := Student{}
json.Unmarshal(b, &s)
fmt.Println(s)
}
After execution, the output is:
{1 john [100,99,98]}