diff --git a/datastructure/set/set.go b/datastructure/set/set.go index 8319144..73da900 100644 --- a/datastructure/set/set.go +++ b/datastructure/set/set.go @@ -181,3 +181,15 @@ func (s Set[T]) EachWithBreak(iteratee func(item T) bool) { } } } + +// Pop delete the top element of set then return it, if set is empty, return nil-value of T and false. +func (s Set[T]) Pop() (v T, ok bool) { + if len(s) > 0 { + items := s.Values() + item := items[len(s)-1] + delete(s, item) + return item, true + } + + return v, false +} diff --git a/datastructure/set/set_test.go b/datastructure/set/set_test.go index be1de88..4fc1f90 100644 --- a/datastructure/set/set_test.go +++ b/datastructure/set/set_test.go @@ -209,3 +209,23 @@ func TestEachWithBreak(t *testing.T) { assert := internal.NewAssert(t, "TestEachWithBreak") assert.Equal(6, sum) } + +func TestPop(t *testing.T) { + assert := internal.NewAssert(t, "TestPop") + + s := NewSet[int]() + + val, ok := s.Pop() + assert.Equal(0, val) + assert.Equal(false, ok) + + s.Add(1) + s.Add(2) + s.Add(3) + + // s = NewSet(1, 2, 3, 4, 5) + + val, ok = s.Pop() + assert.Equal(3, val) + assert.Equal(true, ok) +} diff --git a/docs/datastructure/set.md b/docs/datastructure/set.md index c4f445f..00e3ebb 100644 --- a/docs/datastructure/set.md +++ b/docs/datastructure/set.md @@ -1,16 +1,17 @@ # Set + Set is a data container, like list, but elements of set is not duplicate.
## Source -- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go) - +- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go) ## Usage + ```go import ( set "github.com/duke-git/lancet/v2/datastructure/set" @@ -21,33 +22,32 @@ import ( ## Index -- [NewSet](#NewSet) -- [NewSetFromSlice](#NewSetFromSlice) -- [Values](#Values) -- [Add](#Add) -- [AddIfNotExist](#AddIfNotExist) -- [AddIfNotExistBy](#AddIfNotExistBy) -- [Delete](#Delete) -- [Contain](#Contain) -- [ContainAll](#ContainAll) -- [Clone](#Clone) -- [Size](#Size) -- [Equal](#Equal) -- [Iterate](#Iterate) -- [EachWithBreak](#EachWithBreak) -- [IsEmpty](#IsEmpty) -- [Union](#Union) -- [Intersection](#Intersection) -- [SymmetricDifference](#SymmetricDifference) -- [Minus](#Minus) - - +- [NewSet](#NewSet) +- [NewSetFromSlice](#NewSetFromSlice) +- [Values](#Values) +- [Add](#Add) +- [AddIfNotExist](#AddIfNotExist) +- [AddIfNotExistBy](#AddIfNotExistBy) +- [Delete](#Delete) +- [Contain](#Contain) +- [ContainAll](#ContainAll) +- [Clone](#Clone) +- [Size](#Size) +- [Equal](#Equal) +- [Iterate](#Iterate) +- [EachWithBreak](#EachWithBreak) +- [IsEmpty](#IsEmpty) +- [Union](#Union) +- [Intersection](#Intersection) +- [SymmetricDifference](#SymmetricDifference) +- [Minus](#Minus) ## Documentation ### NewSet +Create a set instance
Signature: @@ -56,6 +56,7 @@ import ( type Set[T comparable] map[T]bool func NewSet[T comparable](items ...T) Set[T] ``` + Example: ```go @@ -72,8 +73,8 @@ func main() { } ``` - ### NewSetFromSlice +Create a set from slice
Signature: @@ -81,6 +82,7 @@ func main() { ```go func NewSetFromSlice[T comparable](items []T) Set[T] ``` + Example: ```go @@ -97,9 +99,8 @@ func main() { } ``` - - ### Values +Return slice of all set data
Signature: @@ -107,6 +108,7 @@ func main() { ```go func (s Set[T]) Values() []T ``` + Example: ```go @@ -123,10 +125,8 @@ func main() { } ``` - - - ### Add +Add items to set
Signature: @@ -134,6 +134,7 @@ func main() { ```go func (s Set[T]) Add(items ...T) ``` + Example: ```go @@ -152,8 +153,8 @@ func main() { } ``` - ### AddIfNotExist +AddIfNotExist checks if item exists in the set, it adds the item to set and returns true if it does not exist in the set, or else it does nothing and returns false.
Signature: @@ -161,6 +162,7 @@ func main() { ```go func (s Set[T]) AddIfNotExist(item T) bool ``` + Example: ```go @@ -176,7 +178,7 @@ func main() { st.Add(1, 2, 3) r1 := st.AddIfNotExist(1) - r2 := st.AddIfNotExist(4) + r2 := st.AddIfNotExist(4) fmt.Println(r1) // false fmt.Println(r2) // true @@ -184,8 +186,8 @@ func main() { } ``` - ### AddIfNotExistBy +AddIfNotExistBy checks if item exists in the set and pass the `checker` function it adds the item to set and returns true if it does not exists in the set and function `checker` returns true, or else it does nothing and returns false.
Signature: @@ -193,6 +195,7 @@ func main() { ```go func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool ``` + Example: ```go @@ -207,23 +210,23 @@ func main() { st := set.NewSet[int]() st.Add(1, 2) - ok := st.AddIfNotExistBy(3, func(val int) bool { - return val%2 != 0 - }) + ok := st.AddIfNotExistBy(3, func(val int) bool { + return val%2 != 0 + }) fmt.Println(ok) // true - notOk := st.AddIfNotExistBy(4, func(val int) bool { - return val%2 != 0 - }) + notOk := st.AddIfNotExistBy(4, func(val int) bool { + return val%2 != 0 + }) fmt.Println(notOk) // false - + fmt.Println(st.Values()) // 1, 2, 3 } ``` - ### Delete +Delete item in set
Signature: @@ -231,6 +234,7 @@ func main() { ```go func (s Set[T]) Delete(items ...T) ``` + Example: ```go @@ -250,9 +254,8 @@ func main() { } ``` - - ### Contain +Check if item is in set or not
Signature: @@ -260,6 +263,7 @@ func main() { ```go func (s Set[T]) Contain(item T) bool ``` + Example: ```go @@ -279,10 +283,8 @@ func main() { } ``` - - - ### ContainAll +Checks if set contains another set
Signature: @@ -290,6 +292,7 @@ func main() { ```go func (s Set[T]) ContainAll(other Set[T]) bool ``` + Example: ```go @@ -302,17 +305,16 @@ import ( func main() { set1 := set.NewSet(1, 2, 3) - set2 := set.NewSet(1, 2) - set3 := set.NewSet(1, 2, 3, 4) + set2 := set.NewSet(1, 2) + set3 := set.NewSet(1, 2, 3, 4) fmt.Println(set1.ContainAll(set2)) //true fmt.Println(set1.ContainAll(set3)) //false } ``` - - ### Size +Get the number of elements in set
Signature: @@ -320,6 +322,7 @@ func main() { ```go func (s Set[T]) Size() int ``` + Example: ```go @@ -337,9 +340,8 @@ func main() { } ``` - - ### Clone +Make a copy of set
Signature: @@ -347,6 +349,7 @@ func main() { ```go func (s Set[T]) Clone() Set[T] ``` + Example: ```go @@ -366,10 +369,8 @@ func main() { } ``` - - - ### Equal +Check if two sets has same elements or not
Signature: @@ -377,6 +378,7 @@ func main() { ```go func (s Set[T]) Equal(other Set[T]) bool ``` + Example: ```go @@ -397,9 +399,8 @@ func main() { } ``` - - ### Iterate +Call function by every element of set
Signature: @@ -407,6 +408,7 @@ func main() { ```go func (s Set[T]) Iterate(fn func(item T)) ``` + Example: ```go @@ -428,8 +430,8 @@ func main() { } ``` - ### EachWithBreak +Iterates over elements of a set and invokes function for each element, when iteratee return false, will break the for each loop.
Signature: @@ -437,6 +439,7 @@ func main() { ```go func (s Set[T]) EachWithBreak(iteratee func(item T) bool) ``` + Example: ```go @@ -450,21 +453,22 @@ import ( func main() { s := set.NewSet(1, 2, 3, 4, 5) - var sum int + var sum int - s.EachWithBreak(func(n int) bool { - if n > 3 { - return false - } - sum += n - return true - }) + s.EachWithBreak(func(n int) bool { + if n > 3 { + return false + } + sum += n + return true + }) fmt.Println(sum) //6 } ``` ### IsEmpty +Check if the set is empty or not
Signature: @@ -472,6 +476,7 @@ func main() { ```go func (s Set[T]) IsEmpty() bool ``` + Example: ```go @@ -491,9 +496,8 @@ func main() { } ``` - - ### Union +Create a new set contain all element of set s and other
Signature: @@ -501,6 +505,7 @@ func main() { ```go func (s Set[T]) Union(other Set[T]) Set[T] ``` + Example: ```go @@ -520,9 +525,8 @@ func main() { } ``` - - ### Intersection +Create a new set whose element both be contained in set s and other
Signature: @@ -530,6 +534,7 @@ func main() { ```go func (s Set[T]) Intersection(other Set[T]) Set[T] ``` + Example: ```go @@ -549,11 +554,8 @@ func main() { } ``` - - - - ### SymmetricDifference +Create a new set whose element is in set1 or set2, but not in both set1 and set2
Signature: @@ -561,6 +563,7 @@ func main() { ```go func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] ``` + Example: ```go @@ -573,18 +576,15 @@ import ( func main() { set1 := set.NewSet(1, 2, 3) - set2 := set.NewSet(2, 3, 4, 5) - set3 := set1.SymmetricDifference(set2) + set2 := set.NewSet(2, 3, 4, 5) + set3 := set1.SymmetricDifference(set2) fmt.Println(set3.Values()) //1,4,5 } ``` - - - - ### Minus +Create an set of whose element in origin set but not in compared set
Signature: @@ -592,6 +592,7 @@ func main() { ```go func (s Set[T]) Minus(comparedSet Set[T]) Set[T] ``` + Example: ```go @@ -604,8 +605,8 @@ import ( func main() { set1 := set.NewSet(1, 2, 3) - set2 := set.NewSet(2, 3, 4, 5) - set3 := set.NewSet(2, 3) + set2 := set.NewSet(2, 3, 4, 5) + set3 := set.NewSet(2, 3) res1 := set1.Minus(set2) fmt.Println(res1.Values()) //1 @@ -615,5 +616,35 @@ func main() { } ``` +### Pop +Delete the top element of set then return it, if set is empty, return nil-value of T and false.
+Signature: + +```go +func (s Set[T]) Pop() (v T, ok bool) +``` + +Example: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + s := set.NewSet[int]() + s.Add(1) + s.Add(2) + s.Add(3) + + val, ok = s.Pop() + + fmt.Println(val) // 3 + fmt.Println(ok) // true +} +``` diff --git a/docs/datastructure/set_zh-CN.md b/docs/datastructure/set_zh-CN.md index ac39619..f978ebf 100644 --- a/docs/datastructure/set_zh-CN.md +++ b/docs/datastructure/set_zh-CN.md @@ -1,16 +1,17 @@ # Set -Set集合数据结构,类似列表。Set中元素不重复。 + +Set 集合数据结构,类似列表。Set 中元素不重复。 ## 源码 -- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go) - +- [https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go](https://github.com/duke-git/lancet/blob/main/datastructure/set/set.go) ## 用法 + ```go import ( set "github.com/duke-git/lancet/v2/datastructure/set" @@ -21,32 +22,31 @@ import ( ## 目录 -- [NewSet](#NewSet) -- [NewSetFromSlice](#NewSetFromSlice) -- [Values](#Values) -- [Add](#Add) -- [AddIfNotExist](#AddIfNotExist) -- [AddIfNotExistBy](#AddIfNotExistBy) -- [Delete](#Delete) -- [Contain](#Contain) -- [ContainAll](#ContainAll) -- [Clone](#Clone) -- [Size](#Size) -- [Equal](#Equal) -- [Iterate](#Iterate) -- [IsEmpty](#IsEmpty) -- [Union](#Union) -- [Intersection](#Intersection) -- [SymmetricDifference](#SymmetricDifference) -- [Minus](#Minus) - - +- [NewSet](#NewSet) +- [NewSetFromSlice](#NewSetFromSlice) +- [Values](#Values) +- [Add](#Add) +- [AddIfNotExist](#AddIfNotExist) +- [AddIfNotExistBy](#AddIfNotExistBy) +- [Delete](#Delete) +- [Contain](#Contain) +- [ContainAll](#ContainAll) +- [Clone](#Clone) +- [Size](#Size) +- [Equal](#Equal) +- [Iterate](#Iterate) +- [IsEmpty](#IsEmpty) +- [Union](#Union) +- [Intersection](#Intersection) +- [SymmetricDifference](#SymmetricDifference) +- [Minus](#Minus) ## 文档 ### NewSet +返回Set结构体对象
函数签名: @@ -55,6 +55,7 @@ import ( type Set[T comparable] map[T]bool func NewSet[T comparable](items ...T) Set[T] ``` + 示例: ```go @@ -71,9 +72,8 @@ func main() { } ``` - - ### NewSetFromSlice +基于切片创建集合
函数签名: @@ -81,6 +81,7 @@ func main() { ```go func NewSetFromSlice[T comparable](items []T) Set[T] ``` + 示例: ```go @@ -97,9 +98,8 @@ func main() { } ``` - - ### Values +获取集合中所有元素的切片
函数签名: @@ -107,6 +107,7 @@ func main() { ```go func (s Set[T]) Values() []T ``` + 示例: ```go @@ -123,10 +124,8 @@ func main() { } ``` - - - ### Add +向集合中添加元素
函数签名: @@ -134,6 +133,7 @@ func main() { ```go func (s Set[T]) Add(items ...T) ``` + 示例: ```go @@ -152,8 +152,8 @@ func main() { } ``` - ### AddIfNotExist +如果集合中不存在元素,则添加该元素返回true, 如果集合中存在元素, 不做任何操作,返回false
函数签名: @@ -161,6 +161,7 @@ func main() { ```go func (s Set[T]) AddIfNotExist(item T) bool ``` + 示例: ```go @@ -176,7 +177,7 @@ func main() { st.Add(1, 2, 3) r1 := st.AddIfNotExist(1) - r2 := st.AddIfNotExist(4) + r2 := st.AddIfNotExist(4) fmt.Println(r1) // false fmt.Println(r2) // true @@ -184,8 +185,8 @@ func main() { } ``` - ### AddIfNotExistBy +根据checker函数判断元素是否在集合中,如果集合中不存在元素且checker返回true,则添加该元素返回true, 否则不做任何操作,返回false
函数签名: @@ -193,6 +194,7 @@ func main() { ```go func (s Set[T]) AddIfNotExistBy(item T, checker func(element T) bool) bool ``` + 示例: ```go @@ -207,24 +209,23 @@ func main() { st := set.NewSet[int]() st.Add(1, 2) - ok := st.AddIfNotExistBy(3, func(val int) bool { - return val%2 != 0 - }) + ok := st.AddIfNotExistBy(3, func(val int) bool { + return val%2 != 0 + }) fmt.Println(ok) // true - notOk := st.AddIfNotExistBy(4, func(val int) bool { - return val%2 != 0 - }) + notOk := st.AddIfNotExistBy(4, func(val int) bool { + return val%2 != 0 + }) fmt.Println(notOk) // false - + fmt.Println(st.Values()) // 1, 2, 3 } ``` - - ### Delete +删除集合中元素
函数签名: @@ -232,6 +233,7 @@ func main() { ```go func (s Set[T]) Delete(items ...T) ``` + 示例: ```go @@ -251,9 +253,8 @@ func main() { } ``` - - ### Contain +判断集合是否包含某个值
函数签名: @@ -261,6 +262,7 @@ func main() { ```go func (s Set[T]) Contain(item T) bool ``` + 示例: ```go @@ -280,10 +282,8 @@ func main() { } ``` - - - ### ContainAll +判断集合是否包含另一个集合
函数签名: @@ -291,6 +291,7 @@ func main() { ```go func (s Set[T]) ContainAll(other Set[T]) bool ``` + 示例: ```go @@ -303,17 +304,16 @@ import ( func main() { set1 := set.NewSet(1, 2, 3) - set2 := set.NewSet(1, 2) - set3 := set.NewSet(1, 2, 3, 4) + set2 := set.NewSet(1, 2) + set3 := set.NewSet(1, 2, 3, 4) fmt.Println(set1.ContainAll(set2)) //true fmt.Println(set1.ContainAll(set3)) //false } ``` - - ### Size +获取集合中元素的个数
函数签名: @@ -321,6 +321,7 @@ func main() { ```go func (s Set[T]) Size() int ``` + 示例: ```go @@ -338,9 +339,8 @@ func main() { } ``` - - ### Clone +克隆一个集合
函数签名: @@ -348,6 +348,7 @@ func main() { ```go func (s Set[T]) Clone() Set[T] ``` + 示例: ```go @@ -367,10 +368,8 @@ func main() { } ``` - - - ### Equal +比较两个集合是否相等,包含相同元素为相等
函数签名: @@ -378,6 +377,7 @@ func main() { ```go func (s Set[T]) Equal(other Set[T]) bool ``` + 示例: ```go @@ -398,9 +398,8 @@ func main() { } ``` - - ### Iterate +迭代结合,在每个元素上调用函数
函数签名: @@ -408,6 +407,7 @@ func main() { ```go func (s Set[T]) Iterate(fn func(item T)) ``` + 示例: ```go @@ -429,8 +429,8 @@ func main() { } ``` - ### EachWithBreak +遍历集合的元素并为每个元素调用iteratee函数,当iteratee函数返回false时,终止遍历。
函数签名: @@ -438,6 +438,7 @@ func main() { ```go func (s Set[T]) EachWithBreak(iteratee func(item T) bool) ``` + 示例: ```go @@ -451,22 +452,22 @@ import ( func main() { s := set.NewSet(1, 2, 3, 4, 5) - var sum int + var sum int - s.EachWithBreak(func(n int) bool { - if n > 3 { - return false - } - sum += n - return true - }) + s.EachWithBreak(func(n int) bool { + if n > 3 { + return false + } + sum += n + return true + }) fmt.Println(sum) //6 } ``` - ### IsEmpty +判断集合是否为空
函数签名: @@ -474,6 +475,7 @@ func main() { ```go func (s Set[T]) IsEmpty() bool ``` + 示例: ```go @@ -493,9 +495,8 @@ func main() { } ``` - - ### Union +求两个集合的并集
函数签名: @@ -503,6 +504,7 @@ func main() { ```go func (s Set[T]) Union(other Set[T]) Set[T] ``` + 示例: ```go @@ -522,9 +524,8 @@ func main() { } ``` - - ### Intersection +求两个集合的交集
函数签名: @@ -532,6 +533,7 @@ func main() { ```go func (s Set[T]) Intersection(other Set[T]) Set[T] ``` + 示例: ```go @@ -551,8 +553,8 @@ func main() { } ``` - ### SymmetricDifference +返回一个集合,其中元素在第一个集合或第二个集合中,且不同时存在于两个集合中
函数签名: @@ -560,6 +562,7 @@ func main() { ```go func (s Set[T]) SymmetricDifference(other Set[T]) Set[T] ``` + 示例: ```go @@ -572,18 +575,15 @@ import ( func main() { set1 := set.NewSet(1, 2, 3) - set2 := set.NewSet(2, 3, 4, 5) - set3 := set1.SymmetricDifference(set2) + set2 := set.NewSet(2, 3, 4, 5) + set3 := set1.SymmetricDifference(set2) fmt.Println(set3.Values()) //1,4,5 } ``` - - - - ### Minus +创建一个集合,其元素在原始集中但不在比较集中
函数签名: @@ -591,6 +591,7 @@ func main() { ```go func (s Set[T]) Minus(comparedSet Set[T]) Set[T] ``` + 示例: ```go @@ -603,8 +604,8 @@ import ( func main() { set1 := set.NewSet(1, 2, 3) - set2 := set.NewSet(2, 3, 4, 5) - set3 := set.NewSet(2, 3) + set2 := set.NewSet(2, 3, 4, 5) + set3 := set.NewSet(2, 3) res1 := set1.Minus(set2) fmt.Println(res1.Values()) //1 @@ -614,5 +615,35 @@ func main() { } ``` +### Pop +删除并返回集合中的顶部元素
+函数签名: + +```go +func (s Set[T]) Pop() (v T, ok bool) +``` + +示例: + +```go +package main + +import ( + "fmt" + set "github.com/duke-git/lancet/v2/datastructure/set" +) + +func main() { + s := set.NewSet[int]() + s.Add(1) + s.Add(2) + s.Add(3) + + val, ok = s.Pop() + + fmt.Println(val) // 3 + fmt.Println(ok) // true +} +```