-
Notifications
You must be signed in to change notification settings - Fork 0
/
slice_util.go
56 lines (45 loc) · 1.32 KB
/
slice_util.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
package jrutil
// CountElements counts the number of times that element occurs in the slice.
func CountElements[T comparable](xs []T) map[T]int {
result := map[T]int{}
for _, x := range xs {
result[x]++
}
return result
}
// SliceToSet returns the set of elements in the slice where the keys
// in the map that return for the elements in the set.
func SliceToSet[T comparable](xs []T) map[T]int {
return CountElements(xs)
}
// SubtractSet returns the set of elements in xs that are not in ys.
// This is the same as the "relative complement" of ys with respect to
// xs. The sets can be generated using [SliceToSet].
func SubtractSet[T comparable](xs, ys map[T]int) map[T]int {
result := map[T]int{}
// Iterate over xs.
for x, count := range xs {
// If the x is not in ys, add it to the result.
_, ok := ys[x]
if !ok {
result[x] = count
}
}
return result
}
// SubtractSlice returns the slice of elements in xs that are not in
// ys. This is the same as the "relative complement" of ys with
// respect to xs.
func SubtractSlice[T comparable](xs, ys []T) []T {
result := []T{}
// Get the set of ys so we can perform quick lookups.
ysSet := SliceToSet(ys)
// Keep only the elements in xs that are not in ys.
for _, x := range xs {
_, ok := ysSet[x]
if !ok {
result = append(result, x)
}
}
return result
}