mirror of
https://github.com/charlienet/go-mixed.git
synced 2025-07-18 00:22:41 +08:00
sets
This commit is contained in:
98
sets/set.go
98
sets/set.go
@ -1,8 +1,102 @@
|
||||
package sets
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/charlienet/go-mixed/locker"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
type Set[T comparable] interface {
|
||||
Add(values ...T)
|
||||
Add(...T)
|
||||
Remove(v T)
|
||||
Contain(value T) bool
|
||||
Asc() Set[T]
|
||||
Desc() Set[T]
|
||||
Contains(T) bool
|
||||
ContainsAny(...T) bool
|
||||
ContainsAll(...T) bool
|
||||
IsEmpty() bool
|
||||
ToSlice() []T // 转换为切片
|
||||
}
|
||||
|
||||
var defaultOptions = option{locker: locker.NewEmptyLocker()}
|
||||
|
||||
type option struct {
|
||||
locker sync.Locker
|
||||
}
|
||||
|
||||
type setFunc func(option)
|
||||
|
||||
func WithSync() setFunc {
|
||||
return func(o option) {
|
||||
o.locker = &sync.RWMutex{}
|
||||
}
|
||||
}
|
||||
|
||||
// 并集
|
||||
func Union[T constraints.Ordered](sets ...Set[T]) Set[T] {
|
||||
if len(sets) == 0 {
|
||||
return NewHashSet[T]()
|
||||
}
|
||||
if len(sets) == 1 {
|
||||
return sets[0]
|
||||
}
|
||||
|
||||
ret := NewHashSet[T]()
|
||||
for i := range sets {
|
||||
ret.Add(sets[i].ToSlice()...)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// 交集
|
||||
func Intersection[T constraints.Ordered](sets ...Set[T]) Set[T] {
|
||||
if len(sets) == 0 {
|
||||
return NewHashSet[T]()
|
||||
}
|
||||
if len(sets) == 1 {
|
||||
return sets[0]
|
||||
}
|
||||
|
||||
ret := NewHashSet[T]()
|
||||
base := sets[0]
|
||||
for _, v := range base.ToSlice() {
|
||||
var insert = true
|
||||
for _, s := range sets[1:] {
|
||||
if !s.Contains(v) {
|
||||
insert = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if insert {
|
||||
ret.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// 差集
|
||||
func Difference[T constraints.Ordered](main Set[T], sets ...Set[T]) Set[T] {
|
||||
if len(sets) == 0 {
|
||||
return main
|
||||
}
|
||||
|
||||
ret := NewHashSet[T]()
|
||||
for _, v := range sets[0].ToSlice() {
|
||||
isDiff := true
|
||||
for _, s := range sets {
|
||||
if s.Contains(v) {
|
||||
isDiff = false
|
||||
}
|
||||
}
|
||||
|
||||
if isDiff {
|
||||
ret.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
Reference in New Issue
Block a user