set.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package utils
  3. import (
  4. "fmt"
  5. "golang.org/x/exp/maps"
  6. )
  7. var _ = fmt.Print
  8. type Set[T comparable] struct {
  9. items map[T]struct{}
  10. }
  11. func (self *Set[T]) Add(val T) {
  12. self.items[val] = struct{}{}
  13. }
  14. func (self *Set[T]) AddItems(val ...T) {
  15. for _, x := range val {
  16. self.items[x] = struct{}{}
  17. }
  18. }
  19. func (self *Set[T]) String() string {
  20. return fmt.Sprintf("%#v", maps.Keys(self.items))
  21. }
  22. func (self *Set[T]) Remove(val T) {
  23. delete(self.items, val)
  24. }
  25. func (self *Set[T]) Discard(val T) {
  26. delete(self.items, val)
  27. }
  28. func (self *Set[T]) Has(val T) bool {
  29. _, ok := self.items[val]
  30. return ok
  31. }
  32. func (self *Set[T]) Len() int {
  33. return len(self.items)
  34. }
  35. func (self *Set[T]) ForEach(f func(T)) {
  36. for x := range self.items {
  37. f(x)
  38. }
  39. }
  40. func (self *Set[T]) Iterable() map[T]struct{} {
  41. return self.items
  42. }
  43. func (self *Set[T]) AsSlice() []T {
  44. return maps.Keys(self.items)
  45. }
  46. func (self *Set[T]) Intersect(other *Set[T]) (ans *Set[T]) {
  47. if other == nil {
  48. return NewSet[T]()
  49. }
  50. if self.Len() < other.Len() {
  51. ans = NewSet[T](self.Len())
  52. for x := range self.items {
  53. if _, ok := other.items[x]; ok {
  54. ans.items[x] = struct{}{}
  55. }
  56. }
  57. } else {
  58. ans = NewSet[T](other.Len())
  59. for x := range other.items {
  60. if _, ok := self.items[x]; ok {
  61. ans.items[x] = struct{}{}
  62. }
  63. }
  64. }
  65. return
  66. }
  67. func (self *Set[T]) Subtract(other *Set[T]) (ans *Set[T]) {
  68. ans = NewSet[T](self.Len())
  69. for x := range self.items {
  70. if other == nil || !other.Has(x) {
  71. ans.items[x] = struct{}{}
  72. }
  73. }
  74. return ans
  75. }
  76. func (self *Set[T]) IsSubsetOf(other *Set[T]) bool {
  77. if other == nil {
  78. return self.Len() == 0
  79. }
  80. for x := range self.items {
  81. if !other.Has(x) {
  82. return false
  83. }
  84. }
  85. return true
  86. }
  87. func NewSet[T comparable](capacity ...int) (ans *Set[T]) {
  88. if len(capacity) == 0 {
  89. ans = &Set[T]{items: make(map[T]struct{}, 8)}
  90. } else {
  91. ans = &Set[T]{items: make(map[T]struct{}, capacity[0])}
  92. }
  93. return
  94. }
  95. func NewSetWithItems[T comparable](items ...T) (ans *Set[T]) {
  96. ans = NewSet[T](len(items))
  97. ans.AddItems(items...)
  98. return ans
  99. }