109 lines
2.0 KiB
Go
109 lines
2.0 KiB
Go
|
package sets
|
|||
|
|
|||
|
// Union returns a union of the given sets (left ∪ right)
|
|||
|
func Union[T comparable](left, right *Set[T]) *Set[T] {
|
|||
|
left.mux.RLock()
|
|||
|
right.mux.RLock()
|
|||
|
defer left.mux.RUnlock()
|
|||
|
defer right.mux.RUnlock()
|
|||
|
|
|||
|
store := map[T]struct{}{}
|
|||
|
|
|||
|
for k := range left.store {
|
|||
|
store[k] = struct{}{}
|
|||
|
}
|
|||
|
for k := range right.store {
|
|||
|
if _, ok := store[k]; !ok {
|
|||
|
store[k] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return &Set[T]{
|
|||
|
store: store,
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Intersection returns an intersection of the given sets (left ∩ right)
|
|||
|
func Intersection[T comparable](left, right *Set[T]) *Set[T] {
|
|||
|
left.mux.RLock()
|
|||
|
right.mux.RLock()
|
|||
|
defer left.mux.RUnlock()
|
|||
|
defer right.mux.RUnlock()
|
|||
|
|
|||
|
store := map[T]struct{}{}
|
|||
|
|
|||
|
for lk := range left.store {
|
|||
|
if _, ok := right.store[lk]; ok {
|
|||
|
store[lk] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return &Set[T]{
|
|||
|
store: store,
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Diff returns the relative complement of sets (left ∖ right)
|
|||
|
func Diff[T comparable](left, right *Set[T]) *Set[T] {
|
|||
|
left.mux.RLock()
|
|||
|
right.mux.RLock()
|
|||
|
defer left.mux.RUnlock()
|
|||
|
defer right.mux.RUnlock()
|
|||
|
|
|||
|
store := map[T]struct{}{}
|
|||
|
|
|||
|
for lk := range left.store {
|
|||
|
if _, ok := right.store[lk]; !ok {
|
|||
|
store[lk] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return &Set[T]{
|
|||
|
store: store,
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// SymmetricDiff returns the symmetric difference between sets (left ⊖ right)
|
|||
|
func SymmetricDiff[T comparable](left, right *Set[T]) *Set[T] {
|
|||
|
left.mux.RLock()
|
|||
|
right.mux.RLock()
|
|||
|
defer left.mux.RUnlock()
|
|||
|
defer right.mux.RUnlock()
|
|||
|
|
|||
|
store := map[T]struct{}{}
|
|||
|
|
|||
|
for lk := range left.store {
|
|||
|
if _, ok := right.store[lk]; !ok {
|
|||
|
store[lk] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
for rk := range right.store {
|
|||
|
if _, ok := left.store[rk]; !ok {
|
|||
|
store[rk] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return &Set[T]{
|
|||
|
store: store,
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Equal checks whether the sets are equal (left = right)
|
|||
|
func Equal[T comparable](left, right *Set[T]) bool {
|
|||
|
left.mux.RLock()
|
|||
|
right.mux.RLock()
|
|||
|
defer left.mux.RUnlock()
|
|||
|
defer right.mux.RUnlock()
|
|||
|
|
|||
|
if len(left.store) != len(right.store) {
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
for lk := range left.store {
|
|||
|
if _, ok := right.store[lk]; !ok {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
return true
|
|||
|
}
|