83 lines
1.5 KiB
Go
83 lines
1.5 KiB
Go
package sets
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
// Set represents a set of values.
|
|
type Set[T comparable] struct {
|
|
store map[T]struct{}
|
|
mux sync.RWMutex
|
|
}
|
|
|
|
// New creates a new set.
|
|
func New[T comparable](data ...T) *Set[T] {
|
|
set := &Set[T]{
|
|
store: map[T]struct{}{},
|
|
}
|
|
|
|
for _, element := range data {
|
|
set.Insert(element)
|
|
}
|
|
return set
|
|
}
|
|
|
|
// NewFromSlice creates a new set from a slice.
|
|
func NewFromSlice[T comparable](data []T) *Set[T] {
|
|
return New[T](data...)
|
|
}
|
|
|
|
// Size returns number of elements in set.
|
|
func (s *Set[T]) Size() int {
|
|
s.mux.RLock()
|
|
defer s.mux.RUnlock()
|
|
|
|
return len(s.store)
|
|
}
|
|
|
|
// Contains checks whether the value is contained in the set.
|
|
func (s *Set[T]) Contains(val T) bool {
|
|
s.mux.RLock()
|
|
defer s.mux.RUnlock()
|
|
|
|
_, ok := s.store[val]
|
|
return ok
|
|
}
|
|
|
|
// Insert inserts a value into the set if the value was not already present.
|
|
func (s *Set[T]) Insert(val T) bool {
|
|
s.mux.Lock()
|
|
defer s.mux.Unlock()
|
|
|
|
if _, ok := s.store[val]; !ok {
|
|
s.store[val] = struct{}{}
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Delete removes a value from the set if the value was already present.
|
|
func (s *Set[T]) Delete(val T) bool {
|
|
s.mux.Lock()
|
|
defer s.mux.Unlock()
|
|
|
|
if _, ok := s.store[val]; ok {
|
|
delete(s.store, val)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Slice returns a slice which contains the elements from the set.
|
|
func (s *Set[T]) Slice() []T {
|
|
s.mux.RLock()
|
|
defer s.mux.RUnlock()
|
|
|
|
elements := []T{}
|
|
for k := range s.store {
|
|
elements = append(elements, k)
|
|
}
|
|
|
|
return elements
|
|
}
|