-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathset.go
152 lines (133 loc) · 3.39 KB
/
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
package sets
// Set sets.Set is a set of `T`,
// implemented via map[T]struct{} for minimal memory consumption.
type Set[T comparable] map[T]struct{}
func newSet[T comparable](cap int) Set[T] {
return make(Set[T], cap)
}
// New creates a T from a list of values.
func New[T comparable](items ...T) Set[T] {
ret := newSet[T](len(items))
return ret.Insert(items...)
}
// NewFrom creates a T from a keys of a map[T](? extends any).
// If the value passed in is not actually a map, this will panic.
func NewFrom[T comparable, V any, M ~map[T]V](m M) Set[T] {
ret := newSet[T](len(m))
for k := range m {
ret[k] = struct{}{}
}
return ret
}
// Insert adds items to the set.
func (s Set[T]) Insert(items ...T) Set[T] {
for _, item := range items {
s[item] = struct{}{}
}
return s
}
// Delete removes all items from the set.
func (s Set[T]) Delete(items ...T) Set[T] {
for _, item := range items {
delete(s, item)
}
return s
}
// Contains returns true if and only if item is contained in the set.
func (s Set[T]) Contains(item T) bool {
_, contained := s[item]
return contained
}
// ContainsAll returns true if and only if all items are contained in the set.
func (s Set[T]) ContainsAll(items ...T) bool {
for _, item := range items {
if !s.Contains(item) {
return false
}
}
return true
}
// ContainsAny returns true if any items are contained in the set.
func (s Set[T]) ContainsAny(items ...T) bool {
for _, item := range items {
if s.Contains(item) {
return true
}
}
return false
}
// Merge is like Union, however it modifies the current set it's applied on
// with the given s2 set.
// For example:
// s1 = {a1, a2}
// s2 = {a3, a4}
// s1.Merge(s2), s1 = {a1, a2, a3, a4}
// s2.Merge(s1), s2 = {a1, a2, a3, a4}.
func (s Set[T]) Merge(s2 Set[T]) Set[T] {
for item := range s2 {
s[item] = struct{}{}
}
return s
}
// IsSuperset returns true if and only if s1 is a superset of s2.
func (s Set[T]) IsSuperset(s2 Set[T]) bool {
for item := range s2 {
if !s.Contains(item) {
return false
}
}
return true
}
// IsSubset returns true if and only if s1 is a superset of s2.
func (s Set[T]) IsSubset(s2 Set[T]) bool {
for item := range s {
if !s2.Contains(item) {
return false
}
}
return true
}
// Equal returns true if and only if s1 is equal (as a set) to s2.
// Two sets are equal if their membership is identical.
// (In practice, this means same elements, order doesn't matter).
func (s Set[T]) Equal(s2 Set[T]) bool {
return len(s) == len(s2) && s.IsSuperset(s2)
}
// Pop Returns a single element from the set.
func (s Set[T]) Pop() (v T, ok bool) {
for key := range s {
delete(s, key)
return key, true
}
return
}
// Len returns the size of the set.
func (s Set[T]) Len() int { return len(s) }
// Clone returns a new Set with a copy of s.
func (s Set[T]) Clone() Set[T] {
return NewFrom(s)
}
// Values returns the value of the sets.
func (s Set[T]) Values() []T {
res := make([]T, 0, len(s))
for key := range s {
res = append(res, key)
}
return res
}
// List returns the value of the sets.
//
// Deprecated: use Values instead.
func (s Set[T]) List() []T {
return s.Values()
}
// Each traverses the items in the Set, calling the provided function for each
// set member. Traversal will continue until all items in the Set have been
// visited, or if the closure returns false.
func (s Set[T]) Each(f func(item T) bool) {
for item := range s {
if !f(item) {
break
}
}
}