github.com/seeker-insurance/kit@v0.0.13/set/string.go (about) 1 package set 2 3 import "sort" 4 5 //String is a set of strings. Remember to initialize with make or String{} 6 type String map[string]signal 7 8 //Contains returns true if the given key is in the set. 9 func (s String) Contains(key string) bool { 10 _, ok := s[key] 11 return ok 12 } 13 14 //Copy copies the set of strings. 15 func (s String) Copy() String { 16 copy := make(String) 17 for k := range s { 18 copy[k] = yes 19 } 20 return copy 21 } 22 23 //Intersection returns a new set containing the intersection of the strings; 24 func (s String) Intersection(strings ...String) (intersection String) { 25 intersection = s.Copy() 26 for key := range s { 27 for _, set := range append(strings, s) { 28 if !set.Contains(key) { 29 delete(intersection, key) 30 } 31 } 32 } 33 return intersection 34 } 35 36 //XOR returns the keys in one set but not the other. 37 func (s String) XOR(other String) String { 38 union := s.Union(other) 39 xor := make(String) 40 for k := range union { 41 if (s.Contains(k) && !other.Contains(k)) || (other.Contains(k) && !s.Contains(k)) { 42 xor[k] = yes 43 } 44 } 45 return xor 46 } 47 48 //Equal shows whether two Strings are equal; i.e, they contain the same items. 49 func (s String) Equal(other String) bool { 50 if len(s) != len(other) { 51 return false 52 } 53 for key := range s { 54 if !other.Contains(key) { 55 return false 56 } 57 } 58 return true 59 } 60 61 //Union returns a new set containing the union of the string sets. 62 func (s String) Union(strings ...String) (union String) { 63 union = s.Copy() 64 for _, set := range strings { 65 for key := range set { 66 union[key] = yes 67 } 68 } 69 return union 70 } 71 72 //IUnion modifies the StringSet in place rather than returning a copy. 73 func (s String) IUnion(strings ...String) { 74 for _, set := range strings { 75 for key := range set { 76 s[key] = yes 77 } 78 } 79 } 80 81 //Difference returns the items in the reciever but not any other arguments 82 func (s String) Difference(strings ...String) (difference String) { 83 difference = s.Copy() 84 for _, set := range strings { 85 for key := range set { 86 delete(difference, key) 87 } 88 } 89 return difference 90 } 91 92 //FromStrings creates a set from strings 93 func FromStrings(strings ...string) String { 94 s := make(String) 95 for _, key := range strings { 96 s[key] = yes 97 } 98 return s 99 } 100 101 //Add a key or key(s) to the set, in-place. Don't call on a nil set. 102 func (s String) Add(keys ...string) { 103 for _, key := range keys { 104 s[key] = yes 105 } 106 } 107 108 //ToSlice returns a slice containing the keys of a set. No order is guaranteed. 109 func (s String) ToSlice() []string { 110 slice := make([]string, len(s)) 111 var i = 0 112 for k := range s { 113 slice[i] = k 114 i++ 115 } 116 return slice 117 } 118 119 //Sorted returns a slice containing the keys of the set in lexigraphic order. 120 func (s String) Sorted() []string { 121 slice := s.ToSlice() 122 sort.Strings(slice) 123 return slice 124 } 125 126 //Map a function f(x) across the set, returning a new set containing f(x) for all x in the set. 127 func (s String) Map(f func(string) string) String { 128 mapped := make(String) 129 for k := range s { 130 mapped[f(k)] = yes 131 } 132 return mapped 133 134 } 135 136 //Reduce applies a reducing function across the set. It will return (0, false) for a set with zero entries. 137 func (s String) Reduce(f func(string, string) string) (string, bool) { 138 if len(s) == 0 { 139 return "", false 140 } 141 first := true 142 var reduced string 143 for k := range s { 144 if first { 145 reduced = k 146 first = false 147 148 } else { 149 reduced = f(reduced, k) 150 } 151 } 152 return reduced, true 153 } 154 155 //Filter applies a filtering function across the set, returning a set containing x where f(x) is true. 156 func (s String) Filter(f func(string) bool) String { 157 filtered := make(String) 158 for k := range s { 159 if f(k) { 160 filtered.Add(k) 161 } 162 } 163 return filtered 164 } 165 166 //IsSubset returns true if every key in s is also in other 167 func (s String) IsSubset(other String) bool { 168 if len(s) > len(other) { 169 return false 170 } 171 172 for k := range s { 173 if _, ok := other[k]; !ok { 174 return false 175 } 176 177 } 178 return true 179 } 180 181 //Remove removes a key from the set, returning the presence of the key. 182 func (s String) Remove(key string) bool { 183 _, ok := s[key] 184 delete(s, key) 185 return ok 186 } 187 188 //Pop an arbitrary element from the set. Returns "", false if no more elements remain. No order, or lack of order, is guaranteed. 189 func (s String) Pop() (k string, more bool) { 190 for k := range s { 191 //iterate 192 delete(s, k) 193 return k, true 194 } 195 return "", false 196 } 197 198 //IsDisjoint returns true if s shared no elements with other. Note that the empty set is disjoint with everything. 199 func (s String) IsDisjoint(other String) bool { 200 for k := range s { 201 if _, ok := other[k]; ok { 202 return false 203 } 204 } 205 return true 206 } 207 208 //IsProperSubset returns true if every key in s is also in other and s != other 209 func (s String) IsProperSubset(other String) bool { 210 return len(s) < len(other) && s.IsSubset(other) 211 } 212 213 //IsSuperset returns true if every key in other is also in s 214 func (s String) IsSuperset(other String) bool { 215 return other.IsSubset(s) 216 } 217 218 //IsProperSuperset returns true if every key in other is also in s and s != other 219 func (s String) IsProperSuperset(other String) bool { 220 return len(s) > len(other) && other.IsSuperset(s) 221 }