sets/set.go
Piotr Icikowski c228caa309
All checks were successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
feat(set): add NewFromSlice function
2024-05-28 00:50:19 +02:00

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
}