summaryrefslogtreecommitdiff
path: root/internal/util/unique.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/util/unique.go')
-rw-r--r--internal/util/unique.go79
1 files changed, 44 insertions, 35 deletions
diff --git a/internal/util/unique.go b/internal/util/unique.go
index f0ded1446..bad553d3f 100644
--- a/internal/util/unique.go
+++ b/internal/util/unique.go
@@ -17,48 +17,57 @@
package util
-import "net/url"
+// Set represents a hashmap of only keys,
+// useful for deduplication / key checking.
+type Set[T comparable] map[T]struct{}
-// UniqueStrings returns a deduplicated version of the given
-// slice of strings, without changing the order of the entries.
-func UniqueStrings(strings []string) []string {
- var (
- l = len(strings)
- keys = make(map[string]any, l) // Use map to dedupe items.
- unique = make([]string, 0, l) // Return slice.
- )
-
- for _, str := range strings {
- // Check if already set as a key in the map;
- // if not, add to return slice + mark key as set.
- if _, set := keys[str]; !set {
- keys[str] = nil // Value doesn't matter.
- unique = append(unique, str)
- }
+// ToSet creates a Set[T] from given values,
+// noting that this does not maintain any order.
+func ToSet[T comparable](in []T) Set[T] {
+ set := make(Set[T], len(in))
+ for _, v := range in {
+ set[v] = struct{}{}
}
-
- return unique
+ return set
}
-// UniqueURIs returns a deduplicated version of the given
-// slice of URIs, without changing the order of the entries.
-func UniqueURIs(uris []*url.URL) []*url.URL {
- var (
- l = len(uris)
- keys = make(map[string]any, l) // Use map to dedupe items.
- unique = make([]*url.URL, 0, l) // Return slice.
- )
+// FromSet extracts the values from set to slice,
+// noting that this does not maintain any order.
+func FromSet[T comparable](in Set[T]) []T {
+ out := make([]T, len(in))
+ var i int
+ for v := range in {
+ out[i] = v
+ i++
+ }
+ return out
+}
- for _, uri := range uris {
- uriStr := uri.String()
+// In returns input slice filtered to
+// only contain those in receiving set.
+func (s Set[T]) In(vs []T) []T {
+ out := make([]T, 0, len(vs))
+ for _, v := range vs {
+ if _, ok := s[v]; ok {
+ out = append(out, v)
+ }
+ }
+ return out
+}
- // Check if already set as a key in the map;
- // if not, add to return slice + mark key as set.
- if _, set := keys[uriStr]; !set {
- keys[uriStr] = nil // Value doesn't matter.
- unique = append(unique, uri)
+// NotIn is the functional inverse of In().
+func (s Set[T]) NotIn(vs []T) []T {
+ out := make([]T, 0, len(vs))
+ for _, v := range vs {
+ if _, ok := s[v]; !ok {
+ out = append(out, v)
}
}
+ return out
+}
- return unique
+// Has returns if value is in Set.
+func (s Set[T]) Has(v T) bool {
+ _, ok := s[v]
+ return ok
}