随机出栈Pop
gset支持Pop()方法,随机出栈一个元素
也支持Pops()方法,随机出栈指定数量的元素
小技巧
GoFrame很多数据类型都支持出栈,要区分是随机出栈还是按顺序出栈的技巧如下:
如果是Pop()
方法是随机出栈
,比如:gset
如果是PopLeft()
、PopRights
()这类方法是指定顺序出栈
的,比如:garray
package main import ( "fmt" "github.com/gogf/gf/container/gset" ) //出栈测试 func main() { var s gset.Set s.Add(1, 2, 3, 4) fmt.Println(s.Pop()) fmt.Println(s.Pops(2)) }
打印结果
我们发现每次打印结果都不一样: 说明Pop()是随机出栈的,popleft这种方法是按顺序出栈的
子集判断
另外一个好用的方法就是子集判断了:IsSubsetOf
package main import ( "fmt" "github.com/gogf/gf/container/gset" ) //子集判断 func main() { s1 := gset.NewFrom([]interface{}{1, 2, 3}) s2 := gset.NewFrom([]interface{}{1, 2, 3, 4}) fmt.Println("s1是s2的子集吗?", s1.IsSubsetOf(s2)) //true fmt.Println("s2是s1的子集吗?", s2.IsSubsetOf(s1)) //false }
打印结果
序列化
使用技巧
- 如果需求是不可重复值,或者需要用交差并补集时,可以设置数据类型为gset类型:gset.Set
- 反序列化时,第二个参数必须是指针类型
package main import ( "encoding/json" "fmt" "github.com/gogf/gf/container/gset" ) func main() { type Student struct { Name string Age int Score *gset.Set //如果需求是不可重复值,或者需要用交差并补集时,建议使用gset类型 } s1 := Student{ Name: "王中阳", Age: 18, Score: gset.NewFrom([]interface{}{100, 98, 98}), } res, _ := json.Marshal(s1) fmt.Println("序列化结果:", string(res)) //序列化结果:{"Name":"王中阳","Age":18,"Score":[100,98]} 98重复,只生效了一个98 set不允许重复元素 // 反序列化 data := []byte(`{"Name":"王中阳","Age":18,"Score":[100,98]}`) s2 := Student{} _ = json.Unmarshal(data, &s2) //第二个参数必须是指针类型 fmt.Println("反序列化:", s2) }
打印结果
通过打印结果我们发现:
序列化结果我们发现在定义的时候虽然设置了两个98,但是只生效了一个98,原因是set不允许重复元素。
遍历修改 walk
使用技巧
- gf提供的数据类型,只要支持walk方法,都表示支持遍历修改
- 遍历修改赋值是非常好用的处理数据的方式
package main import ( "fmt" "github.com/gogf/gf/container/gset" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/util/gconv" ) func main() { var ( s gset.Set tables = g.Slice{"user", "user_goods"} prefix = "my_" ) s.Add(tables...) fmt.Println("walk遍历修改前:", s.Slice()) s.Walk(func(item interface{}) interface{} { return prefix + gconv.String(item) }) fmt.Println("walk遍历修改后:", s.Slice()) }
打印结果