portainer/api/internal/set/set.go

111 lines
1.9 KiB
Go

package set
type SetKey interface {
~int | ~string
}
type Set[T SetKey] map[T]bool
// Add adds a key to the set.
func (s Set[T]) Add(key T) {
s[key] = true
}
// Contains returns true if the set contains the key.
func (s Set[T]) Contains(key T) bool {
_, ok := s[key]
return ok
}
// Remove removes a key from the set.
func (s Set[T]) Remove(key T) {
delete(s, key)
}
// Len returns the number of keys in the set.
func (s Set[T]) Len() int {
return len(s)
}
// IsEmpty returns true if the set is empty.
func (s Set[T]) IsEmpty() bool {
return len(s) == 0
}
// Clear removes all keys from the set.
func (s Set[T]) Keys() []T {
keys := make([]T, s.Len())
i := 0
for k := range s {
keys[i] = k
i++
}
return keys
}
// Clear removes all keys from the set.
func (s Set[T]) Copy() Set[T] {
copy := make(Set[T])
for key := range s {
copy.Add(key)
}
return copy
}
// Difference returns a new set containing the keys that are in the first set but not in the second set.
func (set Set[T]) Difference(second Set[T]) Set[T] {
difference := set.Copy()
for key := range second {
difference.Remove(key)
}
return difference
}
// Union returns a new set containing the keys that are in either set.
func Union[T SetKey](sets ...Set[T]) Set[T] {
union := make(Set[T])
for _, set := range sets {
for key := range set {
union.Add(key)
}
}
return union
}
// Intersection returns a new set containing the keys that are in all sets.
func Intersection[T SetKey](sets ...Set[T]) Set[T] {
if len(sets) == 0 {
return make(Set[T])
}
intersection := sets[0].Copy()
for _, set := range sets[1:] {
for key := range intersection {
if !set.Contains(key) {
intersection.Remove(key)
}
}
}
return intersection
}
// ToSet returns a new set containing the keys.
func ToSet[T SetKey](keys []T) Set[T] {
set := make(Set[T])
for _, key := range keys {
set.Add(key)
}
return set
}