123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
- package utils
- import (
- "fmt"
- )
- var _ = fmt.Print
- func Keys[M ~map[K]V, K comparable, V any](m M) []K {
- r := make([]K, 0, len(m))
- for k := range m {
- r = append(r, k)
- }
- return r
- }
- func Values[M ~map[K]V, K comparable, V any](m M) []V {
- r := make([]V, 0, len(m))
- for _, k := range m {
- r = append(r, k)
- }
- return r
- }
- 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]) String() string {
- return fmt.Sprintf("%#v", Keys(self.items))
- }
- 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]) Clear() {
- clear(self.items)
- }
- 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]) AsSlice() []T {
- return Keys(self.items)
- }
- func (self *Set[T]) Intersect(other *Set[T]) (ans *Set[T]) {
- if other == nil {
- return NewSet[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 (self *Set[T]) Subtract(other *Set[T]) (ans *Set[T]) {
- ans = NewSet[T](self.Len())
- for x := range self.items {
- if other == nil || !other.Has(x) {
- ans.items[x] = struct{}{}
- }
- }
- return ans
- }
- func (self *Set[T]) IsSubsetOf(other *Set[T]) bool {
- if other == nil {
- return self.Len() == 0
- }
- for x := range self.items {
- if !other.Has(x) {
- return false
- }
- }
- return true
- }
- func (self *Set[T]) Equal(other *Set[T]) bool {
- l := self.Len()
- if other == nil {
- return l == 0
- }
- if l != other.Len() {
- return false
- }
- for x := range self.items {
- if !other.Has(x) {
- return false
- }
- }
- return true
- }
- 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
- }
- func NewSetWithItems[T comparable](items ...T) (ans *Set[T]) {
- ans = NewSet[T](len(items))
- ans.AddItems(items...)
- return ans
- }
|