sets/functions.go

109 lines
2.0 KiB
Go
Raw Permalink Normal View History

2023-07-21 23:09:38 +02:00
package sets
2024-05-28 00:44:13 +02:00
// Union returns a union of the given sets (left right).
2023-07-21 23:09:38 +02:00
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,
}
}
2024-05-28 00:44:13 +02:00
// Intersection returns an intersection of the given sets (left ∩ right).
2023-07-21 23:09:38 +02:00
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,
}
}
2024-05-28 00:44:13 +02:00
// Diff returns the relative complement of sets (left right).
2023-07-21 23:09:38 +02:00
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,
}
}
2024-05-28 00:44:13 +02:00
// SymmetricDiff returns the symmetric difference between sets (left ⊖ right).
2023-07-21 23:09:38 +02:00
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,
}
}
2024-05-28 00:44:13 +02:00
// Equal checks whether the sets are equal (left = right).
2023-07-21 23:09:38 +02:00
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
}