forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
at master 2.8 kB view raw
1package sets 2 3import ( 4 "iter" 5 "maps" 6) 7 8type Set[T comparable] struct { 9 data map[T]struct{} 10} 11 12func New[T comparable]() Set[T] { 13 return Set[T]{ 14 data: make(map[T]struct{}), 15 } 16} 17 18func (s *Set[T]) Insert(item T) bool { 19 _, exists := s.data[item] 20 s.data[item] = struct{}{} 21 return !exists 22} 23 24func Singleton[T comparable](item T) Set[T] { 25 n := New[T]() 26 _ = n.Insert(item) 27 return n 28} 29 30func (s *Set[T]) Remove(item T) bool { 31 _, exists := s.data[item] 32 if exists { 33 delete(s.data, item) 34 } 35 return exists 36} 37 38func (s Set[T]) Contains(item T) bool { 39 _, exists := s.data[item] 40 return exists 41} 42 43func (s Set[T]) Len() int { 44 return len(s.data) 45} 46 47func (s Set[T]) IsEmpty() bool { 48 return len(s.data) == 0 49} 50 51func (s *Set[T]) Clear() { 52 s.data = make(map[T]struct{}) 53} 54 55func (s Set[T]) All() iter.Seq[T] { 56 return func(yield func(T) bool) { 57 for item := range s.data { 58 if !yield(item) { 59 return 60 } 61 } 62 } 63} 64 65func (s Set[T]) Clone() Set[T] { 66 return Set[T]{ 67 data: maps.Clone(s.data), 68 } 69} 70 71func (s Set[T]) Union(other Set[T]) iter.Seq[T] { 72 if s.Len() >= other.Len() { 73 return chain(s.All(), other.Difference(s)) 74 } else { 75 return chain(other.All(), s.Difference(other)) 76 } 77} 78 79func chain[T any](seqs ...iter.Seq[T]) iter.Seq[T] { 80 return func(yield func(T) bool) { 81 for _, seq := range seqs { 82 for item := range seq { 83 if !yield(item) { 84 return 85 } 86 } 87 } 88 } 89} 90 91func (s Set[T]) Intersection(other Set[T]) iter.Seq[T] { 92 return func(yield func(T) bool) { 93 for item := range s.data { 94 if other.Contains(item) { 95 if !yield(item) { 96 return 97 } 98 } 99 } 100 } 101} 102 103func (s Set[T]) Difference(other Set[T]) iter.Seq[T] { 104 return func(yield func(T) bool) { 105 for item := range s.data { 106 if !other.Contains(item) { 107 if !yield(item) { 108 return 109 } 110 } 111 } 112 } 113} 114 115func (s Set[T]) SymmetricDifference(other Set[T]) iter.Seq[T] { 116 return func(yield func(T) bool) { 117 for item := range s.data { 118 if !other.Contains(item) { 119 if !yield(item) { 120 return 121 } 122 } 123 } 124 for item := range other.data { 125 if !s.Contains(item) { 126 if !yield(item) { 127 return 128 } 129 } 130 } 131 } 132} 133 134func (s Set[T]) IsSubset(other Set[T]) bool { 135 for item := range s.data { 136 if !other.Contains(item) { 137 return false 138 } 139 } 140 return true 141} 142 143func (s Set[T]) IsSuperset(other Set[T]) bool { 144 return other.IsSubset(s) 145} 146 147func (s Set[T]) IsDisjoint(other Set[T]) bool { 148 for item := range s.data { 149 if other.Contains(item) { 150 return false 151 } 152 } 153 return true 154} 155 156func (s Set[T]) Equal(other Set[T]) bool { 157 if s.Len() != other.Len() { 158 return false 159 } 160 for item := range s.data { 161 if !other.Contains(item) { 162 return false 163 } 164 } 165 return true 166} 167 168func Collect[T comparable](seq iter.Seq[T]) Set[T] { 169 result := New[T]() 170 for item := range seq { 171 result.Insert(item) 172 } 173 return result 174}