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
|
||
}
|