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