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

feat: add UniqueBy function in slice.go

This commit is contained in:
dudaodong
2022-06-22 12:00:01 +08:00
parent 24d4a03227
commit 2d7e19fb87
2 changed files with 34 additions and 0 deletions

View File

@@ -726,6 +726,31 @@ func Unique(slice interface{}) interface{} {
}
// UniqueBy call iteratee func with every item of slice, then remove duplicated.
// The iteratee function signature should be func(value interface{}) interface{}.
func UniqueBy(slice, iteratee interface{}) interface{} {
sv := sliceValue(slice)
fn := functionValue(iteratee)
// elemType := sv.Type().Elem()
// if !checkCallbackFuncSignature2(fn, elemType, elemType) {
// panic("iteratee function signature should be of type func(" + elemType.String() + ")" + elemType.String())
// }
if sv.Len() == 0 {
return slice
}
res := reflect.MakeSlice(sv.Type(), sv.Len(), sv.Len())
for i := 0; i < sv.Len(); i++ {
val := fn.Call([]reflect.Value{sv.Index(i)})[0]
res.Index(i).Set(val)
}
return Unique(res.Interface())
}
// Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
func Union(slices ...interface{}) interface{} {
if len(slices) == 0 {

View File

@@ -418,6 +418,15 @@ func TestUnique(t *testing.T) {
assert.Equal([]string{"a", "b", "c"}, Unique([]string{"a", "a", "b", "c"}))
}
func TestUniqueBy(t *testing.T) {
assert := internal.NewAssert(t, "TestUniqueBy")
actual := UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
assert.Equal([]int{1, 2, 3, 0}, actual)
}
func TestUnion(t *testing.T) {
assert := internal.NewAssert(t, "TestUnion")