package main
import "fmt"
// StringSet is a set of unique strings
type StringSet struct {
m map[string]struct{}
}
func NewStringSet(strings ...string) *StringSet {
res := &StringSet{
m: map[string]struct{}{},
}
for _, s := range strings {
res.Add(s)
}
return res
}
// Add adds a string to the set. If string is already in the set, it has no effect
func (s *StringSet) Add(str string) {
s.m[str] = struct{}{}
}
// Exists checks if string exists in the set
func (s *StringSet) Exists(str string) bool {
_, exists := s.m[str]
return exists
}
// Delete removes a string from the set
func (s *StringSet) Delete(str string) {
delete(s.m, str)
}
// Strings returns strings in the set
func (s *StringSet) Strings() []string {
n := len(s.m)
if n == 0 {
return nil
}
// for efficiency, pre-allocate the array with known, final capacity
// this avoids re-allocating underlying array in append
res := make([]string, 0, n)
for str := range s.m {
res = append(res, str)
}
return res
}
func printExists(set *StringSet, str string) {
if set.Exists(str) {
fmt.Printf("'%s' exists in set\n", str)
} else {
fmt.Printf("'%s' doesn't exist in set\n", str)
}
}
func main() {
set := NewStringSet("hi", "hello")
fmt.Printf("Original set: %#v\n", set.Strings())
set.Delete("hi")
fmt.Printf("After delete: %#v\n", set.Strings())
set.Add("hey")
fmt.Printf("After add : %#v\n", set.Strings())
printExists(set, "hello")
printExists(set, "ola")
}