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
|
package util
// Set is a set data structure.
type Set map[interface{}]interface{}
// SetFromStrings creates a Set containing the strings from the given slice
func SetFromStrings(sl []string) Set {
set := make(Set, len(sl))
for _, item := range sl {
set.Add(item)
}
return set
}
// Hashable is the interface used by set to get the hash code of a value.
// If this isn't given, then the value of the item being added to the set
// itself is used as the comparison value.
type Hashable interface {
Hashcode() interface{}
}
// hashcode returns the hashcode used for set elements.
func hashcode(v interface{}) interface{} {
if h, ok := v.(Hashable); ok {
return h.Hashcode()
}
return v
}
// Add adds an item to the set
func (s Set) Add(v interface{}) {
s[hashcode(v)] = v
}
// Delete removes an item from the set.
func (s Set) Delete(v interface{}) {
delete(s, hashcode(v))
}
// Includes returns true/false of whether a value is in the set.
func (s Set) Includes(v interface{}) bool {
_, ok := s[hashcode(v)]
return ok
}
// Intersection computes the set intersection with other.
func (s Set) Intersection(other Set) Set {
result := make(Set)
if s == nil || other == nil {
return result
}
// Iteration over a smaller set has better performance.
if other.Len() < s.Len() {
s, other = other, s
}
for _, v := range s {
if other.Includes(v) {
result.Add(v)
}
}
return result
}
// Difference returns a set with the elements that s has but
// other doesn't.
func (s Set) Difference(other Set) Set {
result := make(Set)
for k, v := range s {
var ok bool
if other != nil {
_, ok = other[k]
}
if !ok {
result.Add(v)
}
}
return result
}
// Some tests whether at least one element in the array passes the test implemented by the provided function.
// It returns a Boolean value.
func (s Set) Some(cb func(interface{}) bool) bool {
for _, v := range s {
if cb(v) {
return true
}
}
return false
}
// Filter returns a set that contains the elements from the receiver
// where the given callback returns true.
func (s Set) Filter(cb func(interface{}) bool) Set {
result := make(Set)
for _, v := range s {
if cb(v) {
result.Add(v)
}
}
return result
}
// Len is the number of items in the set.
func (s Set) Len() int {
return len(s)
}
// List returns the list of set elements.
func (s Set) List() []interface{} {
if s == nil {
return nil
}
r := make([]interface{}, 0, len(s))
for _, v := range s {
r = append(r, v)
}
return r
}
// UnsafeListOfStrings dangerously casts list to a string
func (s Set) UnsafeListOfStrings() []string {
if s == nil {
return nil
}
r := make([]string, 0, len(s))
for _, v := range s {
r = append(r, v.(string))
}
return r
}
// Copy returns a shallow copy of the set.
func (s Set) Copy() Set {
c := make(Set)
for k, v := range s {
c[k] = v
}
return c
}
|