diff --git a/README.md b/README.md index 5882a34..6e72da6 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,20 @@ Package stl4go is a generic container and algorithm library for go. - [func UniqueCopy[T comparable](a []T) []T](<#func-uniquecopy>) - [func UpperBound[T Ordered](a []T, value T) int](<#func-upperbound>) - [func UpperBoundFunc[T any](a []T, value T, less LessFn[T]) int](<#func-upperboundfunc>) +- [type BuiltinSet](<#type-builtinset>) + - [func MakeBuiltinSetOf[K comparable](ks ...K) BuiltinSet[K]](<#func-makebuiltinsetof>) + - [func (s *BuiltinSet[K]) Clear()](<#func-builtinsetk-clear>) + - [func (s *BuiltinSet[K]) ForEach(cb func(k K))](<#func-builtinsetk-foreach>) + - [func (s *BuiltinSet[K]) ForEachIf(cb func(k K) bool)](<#func-builtinsetk-foreachif>) + - [func (s *BuiltinSet[K]) Has(k K) bool](<#func-builtinsetk-has>) + - [func (s *BuiltinSet[K]) Insert(k K)](<#func-builtinsetk-insert>) + - [func (s *BuiltinSet[K]) InsertN(ks ...K)](<#func-builtinsetk-insertn>) + - [func (s *BuiltinSet[K]) IsEmpty() bool](<#func-builtinsetk-isempty>) + - [func (s *BuiltinSet[K]) Keys() []K](<#func-builtinsetk-keys>) + - [func (s *BuiltinSet[K]) Len() int](<#func-builtinsetk-len>) + - [func (s *BuiltinSet[K]) Remove(k K) bool](<#func-builtinsetk-remove>) + - [func (s *BuiltinSet[K]) RemoveN(ks ...K)](<#func-builtinsetk-removen>) + - [func (s BuiltinSet[K]) String() string](<#func-builtinsetk-string>) - [type CompareFn](<#type-comparefn>) - [type Container](<#type-container>) - [type DList](<#type-dlist>) @@ -111,19 +125,6 @@ Package stl4go is a generic container and algorithm library for go. - [func (q *Queue[T]) PushFront(val T)](<#func-queuet-pushfront>) - [func (q *Queue[T]) String() string](<#func-queuet-string>) - [type Set](<#type-set>) - - [func MakeSetOf[K comparable](ks ...K) Set[K]](<#func-makesetof>) - - [func (s *Set[K]) Add(k K)](<#func-setk-add>) - - [func (s *Set[K]) AddN(ks ...K)](<#func-setk-addn>) - - [func (s *Set[K]) Clear()](<#func-setk-clear>) - - [func (s *Set[K]) Del(k K)](<#func-setk-del>) - - [func (s *Set[K]) DelN(ks ...K)](<#func-setk-deln>) - - [func (s *Set[K]) ForEach(cb func(k K))](<#func-setk-foreach>) - - [func (s *Set[K]) ForEachIf(cb func(k K) bool)](<#func-setk-foreachif>) - - [func (s *Set[K]) Has(k K) bool](<#func-setk-has>) - - [func (s *Set[K]) IsEmpty() bool](<#func-setk-isempty>) - - [func (s *Set[K]) Keys() []K](<#func-setk-keys>) - - [func (s *Set[K]) Len() int](<#func-setk-len>) - - [func (s Set[K]) String() string](<#func-setk-string>) - [type Signed](<#type-signed>) - [type SkipList](<#type-skiplist>) - [func NewSkipList[K Ordered, V any]() *SkipList[K, V]](<#func-newskiplist>) @@ -687,6 +688,94 @@ The elements in the slice a should sorted according with compare func less. Complexity: O\(log\(len\(a\)\)\). +## type [BuiltinSet]() + +BuiltinSet is an associative container that contains a unordered set of unique objects of type K. + +```go +type BuiltinSet[K comparable] map[K]bool +``` + +### func [MakeBuiltinSetOf]() + +```go +func MakeBuiltinSetOf[K comparable](ks ...K) BuiltinSet[K] +``` + +MakeBuiltinSetOf creates a new BuiltinSet object with the initial content from ks. + +### func \(\*BuiltinSet\[K\]\) [Clear]() + +```go +func (s *BuiltinSet[K]) Clear() +``` + +### func \(\*BuiltinSet\[K\]\) [ForEach]() + +```go +func (s *BuiltinSet[K]) ForEach(cb func(k K)) +``` + +### func \(\*BuiltinSet\[K\]\) [ForEachIf]() + +```go +func (s *BuiltinSet[K]) ForEachIf(cb func(k K) bool) +``` + +### func \(\*BuiltinSet\[K\]\) [Has]() + +```go +func (s *BuiltinSet[K]) Has(k K) bool +``` + +### func \(\*BuiltinSet\[K\]\) [Insert]() + +```go +func (s *BuiltinSet[K]) Insert(k K) +``` + +### func \(\*BuiltinSet\[K\]\) [InsertN]() + +```go +func (s *BuiltinSet[K]) InsertN(ks ...K) +``` + +### func \(\*BuiltinSet\[K\]\) [IsEmpty]() + +```go +func (s *BuiltinSet[K]) IsEmpty() bool +``` + +### func \(\*BuiltinSet\[K\]\) [Keys]() + +```go +func (s *BuiltinSet[K]) Keys() []K +``` + +### func \(\*BuiltinSet\[K\]\) [Len]() + +```go +func (s *BuiltinSet[K]) Len() int +``` + +### func \(\*BuiltinSet\[K\]\) [Remove]() + +```go +func (s *BuiltinSet[K]) Remove(k K) bool +``` + +### func \(\*BuiltinSet\[K\]\) [RemoveN]() + +```go +func (s *BuiltinSet[K]) RemoveN(ks ...K) +``` + +### func \(BuiltinSet\[K\]\) [String]() + +```go +func (s BuiltinSet[K]) String() string +``` + ## type [CompareFn]() CompareFn is a 3 way compare function that returns 1 if a \> b, returns 0 if a == b, returns \-1 if a \< b. @@ -943,92 +1032,21 @@ func (q *Queue[T]) PushFront(val T) func (q *Queue[T]) String() string ``` -## type [Set]() - -Set is an associative container that contains a unordered set of unique objects of type K. - -```go -type Set[K comparable] map[K]bool -``` - -### func [MakeSetOf]() - -```go -func MakeSetOf[K comparable](ks ...K) Set[K] -``` - -MakeSetOf creates a new Set object with the initial content from ks. - -### func \(\*Set\[K\]\) [Add]() - -```go -func (s *Set[K]) Add(k K) -``` - -### func \(\*Set\[K\]\) [AddN]() - -```go -func (s *Set[K]) AddN(ks ...K) -``` - -### func \(\*Set\[K\]\) [Clear]() - -```go -func (s *Set[K]) Clear() -``` - -### func \(\*Set\[K\]\) [Del]() - -```go -func (s *Set[K]) Del(k K) -``` - -### func \(\*Set\[K\]\) [DelN]() - -```go -func (s *Set[K]) DelN(ks ...K) -``` - -### func \(\*Set\[K\]\) [ForEach]() - -```go -func (s *Set[K]) ForEach(cb func(k K)) -``` - -### func \(\*Set\[K\]\) [ForEachIf]() - -```go -func (s *Set[K]) ForEachIf(cb func(k K) bool) -``` - -### func \(\*Set\[K\]\) [Has]() - -```go -func (s *Set[K]) Has(k K) bool -``` - -### func \(\*Set\[K\]\) [IsEmpty]() - -```go -func (s *Set[K]) IsEmpty() bool -``` - -### func \(\*Set\[K\]\) [Keys]() - -```go -func (s *Set[K]) Keys() []K -``` - -### func \(\*Set\[K\]\) [Len]() +## type [Set]() -```go -func (s *Set[K]) Len() int -``` - -### func \(Set\[K\]\) [String]() +Set is a containers that store unique elements. ```go -func (s Set[K]) String() string +type Set[K any] interface { + Container + Has(K) bool // Checks whether the container contains element with specific key. + Insert(K) // Inserts a key-value pair in to the container or replace existing value. + InsertN(...K) // Inserts multiple key-value pairs in to the container or replace existing value. + Remove(K) bool // Remove element with specific key. + RemoveN(...K) // Remove multiple elements with specific keys. + ForEach(func(K)) // Iterate the container. + ForEachIf(func(K) bool) // Iterate the container, stops when the callback returns false. +} ``` ## type [Signed]() diff --git a/README_zh.md b/README_zh.md index 3c1cbd5..6a01282 100644 --- a/README_zh.md +++ b/README_zh.md @@ -74,6 +74,20 @@ Package stl4go is a generic container and algorithm library for go. - [func UniqueCopy[T comparable](a []T) []T](<#func-uniquecopy>) - [func UpperBound[T Ordered](a []T, value T) int](<#func-upperbound>) - [func UpperBoundFunc[T any](a []T, value T, less LessFn[T]) int](<#func-upperboundfunc>) +- [type BuiltinSet](<#type-builtinset>) + - [func MakeBuiltinSetOf[K comparable](ks ...K) BuiltinSet[K]](<#func-makebuiltinsetof>) + - [func (s *BuiltinSet[K]) Clear()](<#func-builtinsetk-clear>) + - [func (s *BuiltinSet[K]) ForEach(cb func(k K))](<#func-builtinsetk-foreach>) + - [func (s *BuiltinSet[K]) ForEachIf(cb func(k K) bool)](<#func-builtinsetk-foreachif>) + - [func (s *BuiltinSet[K]) Has(k K) bool](<#func-builtinsetk-has>) + - [func (s *BuiltinSet[K]) Insert(k K)](<#func-builtinsetk-insert>) + - [func (s *BuiltinSet[K]) InsertN(ks ...K)](<#func-builtinsetk-insertn>) + - [func (s *BuiltinSet[K]) IsEmpty() bool](<#func-builtinsetk-isempty>) + - [func (s *BuiltinSet[K]) Keys() []K](<#func-builtinsetk-keys>) + - [func (s *BuiltinSet[K]) Len() int](<#func-builtinsetk-len>) + - [func (s *BuiltinSet[K]) Remove(k K) bool](<#func-builtinsetk-remove>) + - [func (s *BuiltinSet[K]) RemoveN(ks ...K)](<#func-builtinsetk-removen>) + - [func (s BuiltinSet[K]) String() string](<#func-builtinsetk-string>) - [type CompareFn](<#type-comparefn>) - [type Container](<#type-container>) - [type DList](<#type-dlist>) @@ -107,19 +121,6 @@ Package stl4go is a generic container and algorithm library for go. - [func (q *Queue[T]) PushFront(val T)](<#func-queuet-pushfront>) - [func (q *Queue[T]) String() string](<#func-queuet-string>) - [type Set](<#type-set>) - - [func MakeSetOf[K comparable](ks ...K) Set[K]](<#func-makesetof>) - - [func (s *Set[K]) Add(k K)](<#func-setk-add>) - - [func (s *Set[K]) AddN(ks ...K)](<#func-setk-addn>) - - [func (s *Set[K]) Clear()](<#func-setk-clear>) - - [func (s *Set[K]) Del(k K)](<#func-setk-del>) - - [func (s *Set[K]) DelN(ks ...K)](<#func-setk-deln>) - - [func (s *Set[K]) ForEach(cb func(k K))](<#func-setk-foreach>) - - [func (s *Set[K]) ForEachIf(cb func(k K) bool)](<#func-setk-foreachif>) - - [func (s *Set[K]) Has(k K) bool](<#func-setk-has>) - - [func (s *Set[K]) IsEmpty() bool](<#func-setk-isempty>) - - [func (s *Set[K]) Keys() []K](<#func-setk-keys>) - - [func (s *Set[K]) Len() int](<#func-setk-len>) - - [func (s Set[K]) String() string](<#func-setk-string>) - [type Signed](<#type-signed>) - [type SkipList](<#type-skiplist>) - [func NewSkipList[K Ordered, V any]() *SkipList[K, V]](<#func-newskiplist>) @@ -683,6 +684,94 @@ The elements in the slice a should sorted according with compare func less. Complexity: O\(log\(len\(a\)\)\). +## type [BuiltinSet]() + +BuiltinSet is an associative container that contains a unordered set of unique objects of type K. + +```go +type BuiltinSet[K comparable] map[K]bool +``` + +### func [MakeBuiltinSetOf]() + +```go +func MakeBuiltinSetOf[K comparable](ks ...K) BuiltinSet[K] +``` + +MakeBuiltinSetOf creates a new BuiltinSet object with the initial content from ks. + +### func \(\*BuiltinSet\[K\]\) [Clear]() + +```go +func (s *BuiltinSet[K]) Clear() +``` + +### func \(\*BuiltinSet\[K\]\) [ForEach]() + +```go +func (s *BuiltinSet[K]) ForEach(cb func(k K)) +``` + +### func \(\*BuiltinSet\[K\]\) [ForEachIf]() + +```go +func (s *BuiltinSet[K]) ForEachIf(cb func(k K) bool) +``` + +### func \(\*BuiltinSet\[K\]\) [Has]() + +```go +func (s *BuiltinSet[K]) Has(k K) bool +``` + +### func \(\*BuiltinSet\[K\]\) [Insert]() + +```go +func (s *BuiltinSet[K]) Insert(k K) +``` + +### func \(\*BuiltinSet\[K\]\) [InsertN]() + +```go +func (s *BuiltinSet[K]) InsertN(ks ...K) +``` + +### func \(\*BuiltinSet\[K\]\) [IsEmpty]() + +```go +func (s *BuiltinSet[K]) IsEmpty() bool +``` + +### func \(\*BuiltinSet\[K\]\) [Keys]() + +```go +func (s *BuiltinSet[K]) Keys() []K +``` + +### func \(\*BuiltinSet\[K\]\) [Len]() + +```go +func (s *BuiltinSet[K]) Len() int +``` + +### func \(\*BuiltinSet\[K\]\) [Remove]() + +```go +func (s *BuiltinSet[K]) Remove(k K) bool +``` + +### func \(\*BuiltinSet\[K\]\) [RemoveN]() + +```go +func (s *BuiltinSet[K]) RemoveN(ks ...K) +``` + +### func \(BuiltinSet\[K\]\) [String]() + +```go +func (s BuiltinSet[K]) String() string +``` + ## type [CompareFn]() CompareFn is a 3 way compare function that returns 1 if a \> b, returns 0 if a == b, returns \-1 if a \< b. @@ -939,92 +1028,21 @@ func (q *Queue[T]) PushFront(val T) func (q *Queue[T]) String() string ``` -## type [Set]() - -Set is an associative container that contains a unordered set of unique objects of type K. - -```go -type Set[K comparable] map[K]bool -``` - -### func [MakeSetOf]() - -```go -func MakeSetOf[K comparable](ks ...K) Set[K] -``` - -MakeSetOf creates a new Set object with the initial content from ks. - -### func \(\*Set\[K\]\) [Add]() - -```go -func (s *Set[K]) Add(k K) -``` - -### func \(\*Set\[K\]\) [AddN]() - -```go -func (s *Set[K]) AddN(ks ...K) -``` - -### func \(\*Set\[K\]\) [Clear]() - -```go -func (s *Set[K]) Clear() -``` - -### func \(\*Set\[K\]\) [Del]() - -```go -func (s *Set[K]) Del(k K) -``` - -### func \(\*Set\[K\]\) [DelN]() - -```go -func (s *Set[K]) DelN(ks ...K) -``` - -### func \(\*Set\[K\]\) [ForEach]() - -```go -func (s *Set[K]) ForEach(cb func(k K)) -``` - -### func \(\*Set\[K\]\) [ForEachIf]() - -```go -func (s *Set[K]) ForEachIf(cb func(k K) bool) -``` - -### func \(\*Set\[K\]\) [Has]() - -```go -func (s *Set[K]) Has(k K) bool -``` - -### func \(\*Set\[K\]\) [IsEmpty]() - -```go -func (s *Set[K]) IsEmpty() bool -``` - -### func \(\*Set\[K\]\) [Keys]() - -```go -func (s *Set[K]) Keys() []K -``` - -### func \(\*Set\[K\]\) [Len]() +## type [Set]() -```go -func (s *Set[K]) Len() int -``` - -### func \(Set\[K\]\) [String]() +Set is a containers that store unique elements. ```go -func (s Set[K]) String() string +type Set[K any] interface { + Container + Has(K) bool // Checks whether the container contains element with specific key. + Insert(K) // Inserts a key-value pair in to the container or replace existing value. + InsertN(...K) // Inserts multiple key-value pairs in to the container or replace existing value. + Remove(K) bool // Remove element with specific key. + RemoveN(...K) // Remove multiple elements with specific keys. + ForEach(func(K)) // Iterate the container. + ForEachIf(func(K) bool) // Iterate the container, stops when the callback returns false. +} ``` ## type [Signed]() diff --git a/builtin_set.go b/builtin_set.go new file mode 100644 index 0000000..b0f70ec --- /dev/null +++ b/builtin_set.go @@ -0,0 +1,82 @@ +package stl4go + +import ( + "fmt" +) + +// BuiltinSet is an associative container that contains a unordered set of unique objects of type K. +type BuiltinSet[K comparable] map[K]bool + +// MakeBuiltinSetOf creates a new BuiltinSet object with the initial content from ks. +func MakeBuiltinSetOf[K comparable](ks ...K) BuiltinSet[K] { + s := make(BuiltinSet[K]) + s.InsertN(ks...) + return s +} + +func (s *BuiltinSet[K]) IsEmpty() bool { + return len(*s) == 0 +} + +func (s *BuiltinSet[K]) Len() int { + return len(*s) +} + +func (s *BuiltinSet[K]) Clear() { + for k := range *s { + delete(*s, k) + } +} + +func (s *BuiltinSet[K]) Has(k K) bool { + _, ok := (*s)[k] + return ok +} + +func (s *BuiltinSet[K]) Insert(k K) { + (*s)[k] = true +} + +func (s *BuiltinSet[K]) InsertN(ks ...K) { + for _, key := range ks { + (*s)[key] = true + } +} + +func (s *BuiltinSet[K]) Remove(k K) bool { + _, ok := (*s)[k] + delete(*s, k) + return ok +} + +func (s *BuiltinSet[K]) RemoveN(ks ...K) { + for _, k := range ks { + delete(*s, k) + } +} + +func (s *BuiltinSet[K]) Keys() []K { + keys := make([]K, 0, len(*s)) + for k := range *s { + keys = append(keys, k) + } + return keys +} + +func (s *BuiltinSet[K]) ForEach(cb func(k K)) { + for k := range *s { + cb(k) + } +} + +func (s *BuiltinSet[K]) ForEachIf(cb func(k K) bool) { + for k := range *s { + if !cb(k) { + break + } + } +} + +func (s BuiltinSet[K]) String() string { + return fmt.Sprintf("BuiltinSet[%s]%v", nameOfType[K](), s.Keys()) +} diff --git a/builtin_set_test.go b/builtin_set_test.go new file mode 100644 index 0000000..baadceb --- /dev/null +++ b/builtin_set_test.go @@ -0,0 +1,126 @@ +package stl4go + +import ( + "fmt" + "strings" + "testing" +) + +func Test_BuiltinSet_Interface(t *testing.T) { + s := make(BuiltinSet[int]) + _ = Set[int](&s) +} + +func Test_MakeBuiltinSet(t *testing.T) { + s := make(BuiltinSet[string]) + expectEq(t, s.Len(), 0) + expectEq(t, s.IsEmpty(), true) +} + +func Test_MakeBuiltinSet2(t *testing.T) { + s := BuiltinSet[string]{} + expectEq(t, s.Len(), 0) + expectEq(t, s.IsEmpty(), true) +} + +func Test_MakeBuiltinSetOf(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + expectEq(t, s.Len(), 2) +} + +func Test_BuiltinSet_IsEmpty(t *testing.T) { + s := make(BuiltinSet[string]) + expectEq(t, s.IsEmpty(), true) + s.Insert("hello") + expectEq(t, s.IsEmpty(), false) +} + +func Test_BuiltinSet_Clear(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + s.Clear() + expectTrue(t, s.IsEmpty()) +} + +func Test_BuiltinSet_String(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + expectTrue(t, strings.HasPrefix(fmt.Sprintf("%v", s), "BuiltinSet[string]")) +} + +func Test_BuiltinSet_Has(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + expectTrue(t, s.Has("hello")) + expectTrue(t, s.Has("world")) + expectFalse(t, s.Has("!")) +} + +func Test_BuiltinSet_Get(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + expectTrue(t, s["hello"]) + expectTrue(t, s["world"]) + expectFalse(t, s["!"]) +} + +func Test_BuiltinSet_Insert(t *testing.T) { + s := make(BuiltinSet[string]) + s.Insert("hello") + s.Insert("hello") + expectEq(t, s.Has("world"), false) + s.Insert("world") + expectEq(t, s.Has("hello"), true) + expectEq(t, s.Len(), 2) +} + +func Test_BuiltinSet_InsertN(t *testing.T) { + s := make(BuiltinSet[string]) + s.InsertN("hello", "world") + expectEq(t, s.Len(), 2) +} + +func Test_BuiltinSet_Remove(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + s.Remove("hello") + expectEq(t, s.Len(), 1) + s.Remove("hello") + expectEq(t, s.Len(), 1) + s.Remove("world") + expectEq(t, s.Len(), 0) +} + +func Test_BuiltinSet_RemoveN(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + s.RemoveN("hello", "world") + s.Remove("world") + expectTrue(t, s.IsEmpty()) +} + +func Test_BuiltinSet_Keys(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + ks := s.Keys() + expectEq(t, 2, len(ks)) +} + +func Test_BuiltinSet_For(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + for v := range s { + expectTrue(t, v == "hello" || v == "world") + } +} + +func Test_BuiltinSet_ForEach(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + c := 0 + s.ForEach(func(string) { + c++ + }) + expectEq(t, c, 2) +} + +func Test_BuiltinSet_ForEachIf(t *testing.T) { + s := MakeBuiltinSetOf("hello", "world") + c := 0 + s.ForEachIf(func(string) bool { + c++ + return false + }) + expectLt(t, c, 2) +} diff --git a/container.go b/container.go index 93cc138..344b916 100644 --- a/container.go +++ b/container.go @@ -17,3 +17,15 @@ type Map[K any, V any] interface { ForEach(func(K, *V)) // Iterate the container. ForEachIf(func(K, *V) bool) // Iterate the container, stops when the callback returns false. } + +// Set is a containers that store unique elements. +type Set[K any] interface { + Container + Has(K) bool // Checks whether the container contains element with specific key. + Insert(K) // Inserts a key-value pair in to the container or replace existing value. + InsertN(...K) // Inserts multiple key-value pairs in to the container or replace existing value. + Remove(K) bool // Remove element with specific key. + RemoveN(...K) // Remove multiple elements with specific keys. + ForEach(func(K)) // Iterate the container. + ForEachIf(func(K) bool) // Iterate the container, stops when the callback returns false. +} diff --git a/set.go b/set.go deleted file mode 100644 index dcbcdc3..0000000 --- a/set.go +++ /dev/null @@ -1,80 +0,0 @@ -package stl4go - -import ( - "fmt" -) - -// Set is an associative container that contains a unordered set of unique objects of type K. -type Set[K comparable] map[K]bool - -// MakeSetOf creates a new Set object with the initial content from ks. -func MakeSetOf[K comparable](ks ...K) Set[K] { - s := make(Set[K]) - s.AddN(ks...) - return s -} - -func (s *Set[K]) IsEmpty() bool { - return len(*s) == 0 -} - -func (s *Set[K]) Len() int { - return len(*s) -} - -func (s *Set[K]) Clear() { - for k := range *s { - delete(*s, k) - } -} - -func (s *Set[K]) Has(k K) bool { - _, ok := (*s)[k] - return ok -} - -func (s *Set[K]) Add(k K) { - (*s)[k] = true -} - -func (s *Set[K]) AddN(ks ...K) { - for _, key := range ks { - (*s)[key] = true - } -} - -func (s *Set[K]) Del(k K) { - delete(*s, k) -} - -func (s *Set[K]) DelN(ks ...K) { - for _, k := range ks { - delete(*s, k) - } -} - -func (s *Set[K]) Keys() []K { - keys := make([]K, 0, len(*s)) - for k := range *s { - keys = append(keys, k) - } - return keys -} - -func (s *Set[K]) ForEach(cb func(k K)) { - for k := range *s { - cb(k) - } -} - -func (s *Set[K]) ForEachIf(cb func(k K) bool) { - for k := range *s { - if !cb(k) { - break - } - } -} - -func (s Set[K]) String() string { - return fmt.Sprintf("Set[%s]%v", nameOfType[K](), s.Keys()) -} diff --git a/set_test.go b/set_test.go deleted file mode 100644 index 5e26df8..0000000 --- a/set_test.go +++ /dev/null @@ -1,126 +0,0 @@ -package stl4go - -import ( - "fmt" - "strings" - "testing" -) - -func Test_Set_Interface(t *testing.T) { - s := make(Set[int]) - _ = Container(&s) -} - -func Test_MakeSet(t *testing.T) { - s := make(Set[string]) - expectEq(t, s.Len(), 0) - expectEq(t, s.IsEmpty(), true) -} - -func Test_MakeSet2(t *testing.T) { - s := Set[string]{} - expectEq(t, s.Len(), 0) - expectEq(t, s.IsEmpty(), true) -} - -func Test_MakeSetOf(t *testing.T) { - s := MakeSetOf("hello", "world") - expectEq(t, s.Len(), 2) -} - -func Test_Set_IsEmpty(t *testing.T) { - s := make(Set[string]) - expectEq(t, s.IsEmpty(), true) - s.Add("hello") - expectEq(t, s.IsEmpty(), false) -} - -func Test_Set_Clear(t *testing.T) { - s := MakeSetOf("hello", "world") - s.Clear() - expectTrue(t, s.IsEmpty()) -} - -func Test_Set_String(t *testing.T) { - s := MakeSetOf("hello", "world") - expectTrue(t, strings.HasPrefix(fmt.Sprintf("%v", s), "Set[string]")) -} - -func Test_Set_Has(t *testing.T) { - s := MakeSetOf("hello", "world") - expectTrue(t, s.Has("hello")) - expectTrue(t, s.Has("world")) - expectFalse(t, s.Has("!")) -} - -func Test_Set_Get(t *testing.T) { - s := MakeSetOf("hello", "world") - expectTrue(t, s["hello"]) - expectTrue(t, s["world"]) - expectFalse(t, s["!"]) -} - -func Test_Set_Add(t *testing.T) { - s := make(Set[string]) - s.Add("hello") - s.Add("hello") - expectEq(t, s.Has("world"), false) - s.Add("world") - expectEq(t, s.Has("hello"), true) - expectEq(t, s.Len(), 2) -} - -func Test_Set_AddN(t *testing.T) { - s := make(Set[string]) - s.AddN("hello", "world") - expectEq(t, s.Len(), 2) -} - -func Test_Set_Del(t *testing.T) { - s := MakeSetOf("hello", "world") - s.Del("hello") - expectEq(t, s.Len(), 1) - s.Del("hello") - expectEq(t, s.Len(), 1) - s.Del("world") - expectEq(t, s.Len(), 0) -} - -func Test_Set_DelN(t *testing.T) { - s := MakeSetOf("hello", "world") - s.DelN("hello", "world") - s.Del("world") - expectTrue(t, s.IsEmpty()) -} - -func Test_Set_Keys(t *testing.T) { - s := MakeSetOf("hello", "world") - ks := s.Keys() - expectEq(t, 2, len(ks)) -} - -func Test_Set_For(t *testing.T) { - s := MakeSetOf("hello", "world") - for v := range s { - expectTrue(t, v == "hello" || v == "world") - } -} - -func Test_Set_ForEach(t *testing.T) { - s := MakeSetOf("hello", "world") - c := 0 - s.ForEach(func(string) { - c++ - }) - expectEq(t, c, 2) -} - -func Test_Set_ForEachIf(t *testing.T) { - s := MakeSetOf("hello", "world") - c := 0 - s.ForEachIf(func(string) bool { - c++ - return false - }) - expectLt(t, c, 2) -}