1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-04 12:52:28 +08:00

feat: add UniqueByComparator

This commit is contained in:
dudaodong
2024-08-08 11:23:11 +08:00
parent 286e10d189
commit 8611ec0c10
3 changed files with 95 additions and 0 deletions

View File

@@ -808,6 +808,30 @@ func UniqueBy[T any, U comparable](slice []T, iteratee func(item T) U) []T {
return result
}
// UniqueByComparator removes duplicate elements from the input slice using the provided comparator function.
// The function maintains the order of the elements.
// Play: todo
func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T {
result := make([]T, 0, len(slice))
seen := make([]T, 0, len(slice))
for _, item := range slice {
duplicate := false
for _, seenItem := range seen {
if comparator(item, seenItem) {
duplicate = true
break
}
}
if !duplicate {
seen = append(seen, item)
result = append(result, item)
}
}
return result
}
// UniqueByField remove duplicate elements in struct slice by struct field.
// Play: https://go.dev/play/p/6cifcZSPIGu
func UniqueByField[T any](slice []T, field string) ([]T, error) {

View File

@@ -5,6 +5,7 @@ import (
"math"
"reflect"
"strconv"
"strings"
)
func ExampleContain() {
@@ -780,6 +781,23 @@ func ExampleUniqueBy() {
// [1 2 3]
}
func ExampleUniqueByComparator() {
uniqueNums := UniqueByComparator([]int{1, 2, 3, 1, 2, 4, 5, 6, 4}, func(item int, other int) bool {
return item == other
})
caseInsensitiveStrings := UniqueByComparator([]string{"apple", "banana", "Apple", "cherry", "Banana", "date"}, func(item string, other string) bool {
return strings.ToLower(item) == strings.ToLower(other)
})
fmt.Println(uniqueNums)
fmt.Println(caseInsensitiveStrings)
// Output:
// [1 2 3 4 5 6]
// [apple banana cherry date]
}
func ExampleUniqueByField() {
type User struct {
ID int `json:"id"`

View File

@@ -5,6 +5,7 @@ import (
"math"
"reflect"
"strconv"
"strings"
"testing"
"github.com/duke-git/lancet/v2/internal"
@@ -764,6 +765,58 @@ func TestUniqueByField(t *testing.T) {
}, uniqueUsers)
}
func TestUniqueByComparator(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestUniqueByComparator")
t.Run("equal comparison", func(t *testing.T) {
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
comparator := func(item int, other int) bool {
return item == other
}
result := UniqueByComparator(nums, comparator)
assert.Equal([]int{1, 2, 3, 4, 5, 6, 7}, result)
})
t.Run("unique struct slice by field", func(t *testing.T) {
type student struct {
Name string
Age int
}
students := []student{
{Name: "a", Age: 11},
{Name: "b", Age: 12},
{Name: "a", Age: 13},
{Name: "c", Age: 14},
}
comparator := func(item, other student) bool { return item.Name == other.Name }
result := UniqueByComparator(students, comparator)
assert.Equal([]student{
{Name: "a", Age: 11},
{Name: "b", Age: 12},
{Name: "c", Age: 14},
}, result)
})
t.Run("case-insensitive string comparison", func(t *testing.T) {
stringSlice := []string{"apple", "banana", "Apple", "cherry", "Banana", "date"}
caseInsensitiveComparator := func(item, other string) bool {
return strings.ToLower(item) == strings.ToLower(other)
}
result := UniqueByComparator(stringSlice, caseInsensitiveComparator)
assert.Equal([]string{"apple", "banana", "cherry", "date"}, result)
})
}
func TestUnion(t *testing.T) {
t.Parallel()