File size: 1,814 Bytes
6380833 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | package set
import "sync"
type Set[T comparable] struct {
mu sync.RWMutex
content map[T]struct{}
}
func New[T comparable](items ...T) *Set[T] {
s := Set[T]{
content: make(map[T]struct{}, len(items)),
}
s.Add(items...)
return &s
}
func (s *Set[T]) Add(items ...T) {
s.mu.Lock()
defer s.mu.Unlock()
for _, item := range items {
s.content[item] = struct{}{}
}
}
func (s *Set[T]) Remove(items ...T) {
s.mu.Lock()
defer s.mu.Unlock()
for _, item := range items {
delete(s.content, item)
}
}
func (s *Set[T]) Has(item T) bool {
s.mu.RLock()
defer s.mu.RUnlock()
_, exists := s.content[item]
return exists
}
func (s *Set[T]) AsSlice() []T {
s.mu.RLock()
defer s.mu.RUnlock()
result := make([]T, 0, len(s.content))
for item := range s.content {
result = append(result, item)
}
return result
}
func (s *Set[T]) IsEmpty() bool {
s.mu.RLock()
defer s.mu.RUnlock()
return len(s.content) == 0
}
// Subtract removes all items from a that are also in b
func Subtract[T comparable](a *Set[T], b ...*Set[T]) *Set[T] {
a.mu.RLock()
defer a.mu.RUnlock()
for _, set := range b {
set.mu.RLock()
defer set.mu.RUnlock()
}
result := Set[T]{
content: make(map[T]struct{}, len(a.content)),
}
for item := range a.content {
result.content[item] = struct{}{}
}
for _, set := range b {
for item := range set.content {
delete(result.content, item)
}
}
return &result
}
func Union[T comparable](sets ...*Set[T]) *Set[T] {
for _, set := range sets {
set.mu.RLock()
defer set.mu.RUnlock()
}
outLen := 0
for _, set := range sets {
outLen += len(set.content)
}
result := Set[T]{
content: make(map[T]struct{}, outLen),
}
for _, set := range sets {
for item := range set.content {
result.content[item] = struct{}{}
}
}
return &result
}
|