package tools
type StringSet map[string]struct{}
func NewStringSet() StringSet {
return make(StringSet)
}
func NewStringSetWithCapacity(capacity int) StringSet {
return make(StringSet, capacity)
}
func NewStringSetFromSlice(s []string) StringSet {
a := NewStringSetWithCapacity(len(s))
for _, item := range s {
a.Add(item)
}
return a
}
func (set StringSet) Add(i string) bool {
_, found := set[i]
set[i] = struct{}{}
return !found
}
func (set StringSet) Contains(i string) bool {
_, found := set[i]
return found
}
func (set StringSet) ContainsAll(i ...string) bool {
allSet := NewStringSetFromSlice(i)
if allSet.IsSubset(set) {
return true
}
return false
}
func (set StringSet) IsSubset(other StringSet) bool {
for elem := range set {
if !other.Contains(elem) {
return false
}
}
return true
}
func (set StringSet) IsSuperset(other StringSet) bool {
return other.IsSubset(set)
}
func (set StringSet) Union(other StringSet) StringSet {
unionedSet := NewStringSet()
for elem := range set {
unionedSet.Add(elem)
}
for elem := range other {
unionedSet.Add(elem)
}
return unionedSet
}
func (set StringSet) Intersect(other StringSet) StringSet {
intersection := NewStringSet()
if set.Cardinality() < other.Cardinality() {
for elem := range set {
if other.Contains(elem) {
intersection.Add(elem)
}
}
} else {
for elem := range other {
if set.Contains(elem) {
intersection.Add(elem)
}
}
}
return intersection
}
func (set StringSet) Difference(other StringSet) StringSet {
differencedSet := NewStringSet()
for elem := range set {
if !other.Contains(elem) {
differencedSet.Add(elem)
}
}
return differencedSet
}
func (set StringSet) SymmetricDifference(other StringSet) StringSet {
aDiff := set.Difference(other)
bDiff := other.Difference(set)
return aDiff.Union(bDiff)
}
func (set *StringSet) Clear() {
*set = make(StringSet)
}
func (set StringSet) Remove(i string) {
delete(set, i)
}
func (set StringSet) Cardinality() int {
return len(set)
}
func (set StringSet) Iter() <-chan string {
ch := make(chan string)
go func() {
for elem := range set {
ch <- elem
}
close(ch)
}()
return ch
}
func (set StringSet) Equal(other StringSet) bool {
if set.Cardinality() != other.Cardinality() {
return false
}
for elem := range set {
if !other.Contains(elem) {
return false
}
}
return true
}
func (set StringSet) Clone() StringSet {
clonedSet := NewStringSet()
for elem := range set {
clonedSet.Add(elem)
}
return clonedSet
}