sets/functions.go

109 lines
2.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}