Skip to content

Commit d66071c

Browse files
committed
Remove comparable constraint from DedupBy
I couldn't see any reason for DedupBy to require elements in the slice to be comparable, since the comparison is done by the function. This change relaxes the `comparable` constraint and adds a test case to prove that non-comparable types can be deduped.
1 parent 83c9345 commit d66071c

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

slices/slice_func.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func CountBy[S ~[]T, T any](items S, f func(el T) bool) int {
6565

6666
// DedupBy returns a copy of items, but without consecutive elements
6767
// for which f returns the same result.
68-
func DedupBy[S ~[]T, T comparable, G comparable](items S, f func(el T) G) S {
68+
func DedupBy[S ~[]T, T any, G comparable](items S, f func(el T) G) S {
6969
result := make(S, 0, len(items))
7070
if len(items) == 0 {
7171
return result

slices/slice_func_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ func TestDedupBy(t *testing.T) {
7878
f([]int{1, 2, 3}, []int{1, 2, 3})
7979
f([]int{1, 2, 2, 3}, []int{1, 2, 3})
8080
f([]int{1, 2, 4, 3, 5, 7, 10}, []int{1, 2, 3, 10})
81+
82+
// DedupBy supports non-comparable types.
83+
g := func(given [][]int, expected [][]int) {
84+
first := func(s []int) int { return s[0] }
85+
actual := slices.DedupBy(given, first)
86+
is.Equal(actual, expected)
87+
}
88+
g([][]int{{1}, {1}}, [][]int{{1}})
89+
g([][]int{{1}, {1, 2}}, [][]int{{1}})
8190
}
8291

8392
func TestDropWhile(t *testing.T) {

0 commit comments

Comments
 (0)