-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathset.go
267 lines (245 loc) · 6.71 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
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
package g
// Union takes two slices and returns a new slice that contains
// all unique items from both slices. The type T must be comparable.
//
// It removes duplicates and returns the union of the slices.
//
// The function is generic and can work with any type T that
// is comparable.
//
// Note: This function does not preserve the order of elements.
// The order of elements in the returned slice can be different
// from the order of elements in the input slices.
//
// Example usage:
//
// a := []int{1, 2, 3}
// b := []int{3, 4, 5}
// result := g.Union(a, b)
// fmt.Println(result) // Output: [1 2 3 4 5]
//
// a := []string{"a", "b", "c"}
// b := []string{"c", "d", "e"}
// result := g.Union(a, b)
// fmt.Println(result) // Output: [a b c d e]
func Union[T comparable](a []T, b []T) []T {
distinctValues := map[T]bool{}
for _, val := range a {
distinctValues[val] = true
}
for _, val := range b {
distinctValues[val] = true
}
result := make([]T, 0, len(distinctValues))
for val := range distinctValues {
result = append(result, val)
}
return result
}
// Intersection takes two slices and returns a new slice that
// contains the common items present in both slices. The type T
// must be comparable.
//
// The function returns the intersection of the slices.
//
// The function is generic and can work with any type T that
// is comparable.
//
// Note: This function does not preserve the order of elements.
// The order of elements in the returned slice can be different
// from the order of elements in the input slices.
//
// Example usage:
//
// a := []int{1, 2, 3}
// b := []int{3, 4, 5}
// result := g.Intersection(a, b)
// fmt.Println(result) // Output: [3]
//
// a := []string{"a", "b", "c"}
// b := []string{"c", "d", "e"}
// result := g.Intersection(a, b)
// fmt.Println(result) // Output: [c]
func Intersection[T comparable](a []T, b []T) []T {
m1 := make(map[T]bool)
for _, item := range a {
m1[item] = true
}
m2 := make(map[T]bool)
for _, item := range b {
m2[item] = true
}
result := make([]T, 0)
for item := range m1 {
if m2[item] {
result = append(result, item)
}
}
return result
}
// Difference takes two slices and returns a new slice that
// contains the items present in the first slice but not in the
// second slice. The type T must be comparable.
//
// The function returns the difference of the slices.
//
// The function is generic and can work with any type T that
// is comparable.
//
// Note: This function does not preserve the order of elements.
// The order of elements in the returned slice can be different
// from the order of elements in the input slices.
//
// Example usage:
//
// a := []int{1, 2, 3}
// b := []int{3, 4, 5}
// result := g.Difference(a, b)
// fmt.Println(result) // Output: [1, 2]
//
// a := []string{"a", "b", "c"}
// b := []string{"c", "d", "e"}
// result := g.Difference(a, b)
// fmt.Println(result) // Output: ["a", "b"]
func Difference[T comparable](a []T, b []T) []T {
m1 := make(map[T]bool)
for _, item := range a {
m1[item] = true
}
m2 := make(map[T]bool)
for _, item := range b {
m2[item] = true
}
result := make([]T, 0)
for item := range m1 {
if !m2[item] {
result = append(result, item)
}
}
return result
}
// Diff is an alias for Difference function.
func Diff[T comparable](a []T, b []T) []T {
return Difference(a, b)
}
// SymmetricDifference takes two slices and returns a new slice
// that contains the items present in one of the slices but not in both.
// The type T must be comparable.
//
// The function returns the symmetric difference of the slices.
//
// The function is generic and can work with any type T that
// is comparable.
//
// Note: This function does not preserve the order of elements.
// The order of elements in the returned slice can be different
// from the order of elements in the input slices.
//
// Example usage:
//
// a := []int{1, 2, 3}
// b := []int{3, 4, 5}
// result := g.SymmetricDifference(a, b)
// fmt.Println(result) // Output: [1, 2, 4, 5]
//
// a := []string{"a", "b", "c"}
// b := []string{"c", "d", "e"}
// result := g.SymmetricDifference(a, b)
// fmt.Println(result) // Output: ["a", "b", "d", "e"]
func SymmetricDifference[T comparable](a []T, b []T) []T {
m1 := make(map[T]bool)
for _, item := range a {
m1[item] = true
}
m2 := make(map[T]bool)
for _, item := range b {
m2[item] = true
}
result := make([]T, 0)
for item := range m1 {
if !m2[item] {
result = append(result, item)
}
}
for item := range m2 {
if !m1[item] {
result = append(result, item)
}
}
return result
}
// Sdiff is an alias for SymmetricDifference function.
func Sdiff[T comparable](a []T, b []T) []T {
return SymmetricDifference(a, b)
}
// Complement takes a universal set (b) and a subset of it (a) and
// Output: a new slice containing items present in the universal set
// but not in the subset. The type T must be comparable.
//
// The function returns the complement of the subset.
//
// The function is generic and can work with any type T that
// is comparable.
//
// Note: This function does not preserve the order of elements.
// The order of elements in the returned slice can be different
// from the order of elements in the input slices.
//
// Example usage:
//
// u := []int{1, 2, 3, 4, 5}
// a := []int{1, 2, 3}
// result := g.Complement(a, u)
// fmt.Println(result) // Output: [4, 5]
//
// u := []string{"a", "b", "c", "d", "e"}
// a := []string{"a", "b", "c"}
// result := g.Complement(a, u)
// fmt.Println(result) // Output: ["d", "e"]
func Complement[T comparable](a []T, b []T) []T {
m1 := make(map[T]bool)
for _, item := range a {
m1[item] = true
}
result := make([]T, 0)
for _, item := range b {
if !m1[item] {
result = append(result, item)
}
}
return result
}
// CartesianProduct returns all possible pairs from two slices.
//
// The function generates a slice of pairs, where each pair
// consists of an element from the first input slice and an
// element from the second input slice. The length of the
// returned slice is equal to the product of the lengths of
// the input slices.
//
// This function is generic and can work with any type T.
//
// Note: This function does not preserve the order of elements.
// The order of elements in the returned slice can be different
// from the order of elements in the input slices.
//
// Example usage:
//
// a := []int{1, 2}
// b := []int{3, 4}
// result := g.CartesianProduct(a, b)
// // Output: [[1, 3], [1, 4], [2, 3], [2, 4]]
//
// x := []string{"A", "B"}
// y := []string{"C", "D"}
// result := g.CartesianProduct(x, y)
// // Output: [["A", "C"], ["A", "D"], ["B", "C"], ["B", "D"]]
func CartesianProduct[T any](a []T, b []T) [][2]T {
var result [][2]T
for _, itemA := range a {
for _, itemB := range b {
result = append(result, [2]T{itemA, itemB})
}
}
return result
}