-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunique.go
63 lines (51 loc) · 1.4 KB
/
unique.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
package slices2
// Unique gets only unique elements.
//
// Returns new slice with duplicates removed.
func Unique[S ~[]E, E comparable](s S) S {
if len(s) <= 1 {
return Clone(s) // a copy of
}
return uniqueBy(initNew[S, E], me[E], s)
}
// UniqueBy gets only unique elements by custom key.
//
// Returns new slice with duplicates removed.
func UniqueBy[S ~[]E, K comparable, E any](byFn func(E) K, s S) S {
if len(s) <= 1 {
return Clone(s) // a copy of
}
return uniqueBy(initNew[S, E], byFn, s)
}
// UniqueInPlace gets only unique elements.
//
// Returns original slice with duplicates removed in-place.
func UniqueInPlace[S ~[]E, E comparable](s S) S {
if len(s) <= 1 {
return s // as is
}
return uniqueBy(initSame[S, E], me[E], s)
}
// UniqueInPlaceBy gets only unique elements by custom key.
//
// Returns original slice with duplicates removed in-place.
func UniqueInPlaceBy[S ~[]E, K comparable, E any](byFn func(E) K, s S) S {
if len(s) <= 1 {
return s // as is
}
return uniqueBy(initSame[S, E], byFn, s)
}
// uniqueBy gets only unique elements by custom key.
func uniqueBy[S ~[]E, K comparable, E any](initFn func(S) S, byFn func(E) K, s S) S {
seen := make(map[K]struct{}, len(s))
out := initFn(s) // copy or share
for _, v := range s {
key := byFn(v)
if _, ok := seen[key]; ok {
continue // ignore, already seen
}
seen[key] = struct{}{}
out = append(out, v)
}
return out
}