forked from chen3feng/stl4go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
builtin_set.go
181 lines (157 loc) · 3.92 KB
/
builtin_set.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package stl4go
import (
"fmt"
)
// BuiltinSet is an associative container that contains an unordered set of unique objects of type K.
type BuiltinSet[K comparable] map[K]struct{}
// SetOf creates a new BuiltinSet object with the initial content from ks.
func SetOf[K comparable](ks ...K) BuiltinSet[K] {
s := make(BuiltinSet[K])
s.InsertN(ks...)
return s
}
// IsEmpty implements the Container interface.
func (s BuiltinSet[K]) IsEmpty() bool {
return len(s) == 0
}
// Len implements the Container interface.
func (s BuiltinSet[K]) Len() int {
return len(s)
}
// Clear implements the Container interface.
func (s BuiltinSet[K]) Clear() {
for k := range s {
delete(s, k)
}
}
// Has implements the Set interface.
func (s BuiltinSet[K]) Has(k K) bool {
_, ok := s[k]
return ok
}
// Insert implements the Set interface.
func (s BuiltinSet[K]) Insert(k K) bool {
oldLen := len(s)
s[k] = struct{}{}
return len(s) > oldLen
}
// InsertN implements the Set interface.
func (s BuiltinSet[K]) InsertN(ks ...K) int {
oldLen := len(s)
for _, key := range ks {
s[key] = struct{}{}
}
return len(s) - oldLen
}
// Remove implements the Set interface.
func (s BuiltinSet[K]) Remove(k K) bool {
_, ok := s[k]
delete(s, k)
return ok
}
// Delete deletes an element from the set.
// It returns nothing, so it's faster than Remove.
func (s BuiltinSet[K]) Delete(k K) {
delete(s, k)
}
// RemoveN implements the Set interface.
func (s BuiltinSet[K]) RemoveN(ks ...K) int {
oldLen := len(s)
for _, k := range ks {
delete(s, k)
}
return oldLen - len(s)
}
// Keys return a copy of all keys as a slice.
func (s BuiltinSet[K]) Keys() []K {
keys := make([]K, 0, len(s))
for k := range s {
keys = append(keys, k)
}
return keys
}
// ForEach implements the Set interface.
func (s BuiltinSet[K]) ForEach(cb func(k K)) {
for k := range s {
cb(k)
}
}
// ForEachIf implements the Container interface.
func (s BuiltinSet[K]) ForEachIf(cb func(k K) bool) {
for k := range s {
if !cb(k) {
break
}
}
}
// String implements the fmt.Stringer interface.
func (s BuiltinSet[K]) String() string {
return fmt.Sprintf("BuiltinSet[%s]%v", nameOfType[K](), s.Keys())
}
// Update adds all elements from other to set. set |= other.
func (s BuiltinSet[K]) Update(other BuiltinSet[K]) {
for k := range other {
s[k] = struct{}{}
}
}
// Union returns a new set with elements from the set and other.
func (s BuiltinSet[K]) Union(other BuiltinSet[K]) BuiltinSet[K] {
result := BuiltinSet[K]{}
result.Update(s)
result.Update(other)
return result
}
func orderSet[K comparable](a, b BuiltinSet[K]) (small, large BuiltinSet[K]) {
if a.Len() < b.Len() {
return a, b
}
return b, a
}
// Intersection returns a new set with elements common to the set and other.
func (s BuiltinSet[K]) Intersection(other BuiltinSet[K]) BuiltinSet[K] {
result := BuiltinSet[K]{}
small, large := orderSet(s, other)
for k := range small {
if large.Has(k) {
result.Insert(k)
}
}
return result
}
// Difference returns a new set with elements in the set that are not in other.
func (s BuiltinSet[K]) Difference(other BuiltinSet[K]) BuiltinSet[K] {
result := BuiltinSet[K]{}
for k := range s {
if !other.Has(k) {
result.Insert(k)
}
}
return result
}
// IsDisjointOf return True if the set has no elements in common with other.
// Sets are disjoint if and only if their intersection is the empty set.
func (s BuiltinSet[K]) IsDisjointOf(other BuiltinSet[K]) bool {
small, large := orderSet(s, other)
for k := range small {
if large.Has(k) {
return false
}
}
return true
}
// IsSubsetOf tests whether every element in the set is in other.
func (s BuiltinSet[K]) IsSubsetOf(other BuiltinSet[K]) bool {
if s.Len() > other.Len() {
return false
}
for k := range s {
if !other.Has(k) {
return false
}
}
return true
}
// IsSupersetOf tests whether every element in other is in the set.
func (s BuiltinSet[K]) IsSupersetOf(other BuiltinSet[K]) bool {
return other.IsSubsetOf(s)
}