From befd5a65c32b4780f1eb01c5b58e5ac72bc22f88 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 9 Feb 2023 18:00:04 +0530 Subject: [PATCH] A generic Set implementation --- tools/utils/set.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 tools/utils/set.go diff --git a/tools/utils/set.go b/tools/utils/set.go new file mode 100644 index 000000000..56b8db0d3 --- /dev/null +++ b/tools/utils/set.go @@ -0,0 +1,78 @@ +// License: GPLv3 Copyright: 2023, Kovid Goyal, + +package utils + +import ( + "fmt" +) + +var _ = fmt.Print + +type Set[T comparable] struct { + items map[T]struct{} +} + +func (self *Set[T]) Add(val T) { + self.items[val] = struct{}{} +} + +func (self *Set[T]) AddItems(val ...T) { + for _, x := range val { + self.items[x] = struct{}{} + } +} + +func (self *Set[T]) Remove(val T) { + delete(self.items, val) +} + +func (self *Set[T]) Discard(val T) { + delete(self.items, val) +} + +func (self *Set[T]) Has(val T) bool { + _, ok := self.items[val] + return ok +} + +func (self *Set[T]) Len() int { + return len(self.items) +} + +func (self *Set[T]) ForEach(f func(T)) { + for x := range self.items { + f(x) + } +} + +func (self *Set[T]) Iterable() map[T]struct{} { + return self.items +} + +func (self *Set[T]) Intersect(other *Set[T]) (ans *Set[T]) { + if self.Len() < other.Len() { + ans = NewSet[T](self.Len()) + for x := range self.items { + if _, ok := other.items[x]; ok { + ans.items[x] = struct{}{} + } + } + } else { + ans = NewSet[T](other.Len()) + for x := range other.items { + if _, ok := self.items[x]; ok { + ans.items[x] = struct{}{} + } + } + } + return +} + +func NewSet[T comparable](capacity ...int) (ans *Set[T]) { + if len(capacity) == 0 { + ans = &Set[T]{items: make(map[T]struct{}, 8)} + } else { + ans = &Set[T]{items: make(map[T]struct{}, capacity[0])} + } + return +}