mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-17 11:12:28 +08:00
refactor: sort (#21)
Removed reverse func because it use to much cpu and add test cas for asc sort
This commit is contained in:
@@ -523,18 +523,38 @@ func SortByField(slice interface{}, field string, sortType ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a less function based on the field's kind.
|
// Create a less function based on the field's kind.
|
||||||
var less func(a, b reflect.Value) bool
|
var compare func(a, b reflect.Value) bool
|
||||||
switch sf.Type.Kind() {
|
switch sf.Type.Kind() {
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
|
if len(sortType) > 0 && sortType[0] == "desc" {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.Int() > b.Int() }
|
||||||
|
} else {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
|
||||||
|
}
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
|
if len(sortType) > 0 && sortType[0] == "desc" {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.Uint() > b.Uint() }
|
||||||
|
} else {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
|
||||||
|
}
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
less = func(a, b reflect.Value) bool { return a.Float() < b.Float() }
|
if len(sortType) > 0 && sortType[0] == "desc" {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.Float() > b.Float() }
|
||||||
|
} else {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.Float() < b.Float() }
|
||||||
|
}
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
less = func(a, b reflect.Value) bool { return a.String() < b.String() }
|
if len(sortType) > 0 && sortType[0] == "desc" {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.String() > b.String() }
|
||||||
|
} else {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.String() < b.String() }
|
||||||
|
}
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() }
|
if len(sortType) > 0 && sortType[0] == "desc" {
|
||||||
|
compare = func(a, b reflect.Value) bool { return a.Bool() && !b.Bool() }
|
||||||
|
} else {
|
||||||
|
compare = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() }
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("field type %s not supported", sf.Type)
|
return fmt.Errorf("field type %s not supported", sf.Type)
|
||||||
}
|
}
|
||||||
@@ -548,24 +568,12 @@ func SortByField(slice interface{}, field string, sortType ...string) error {
|
|||||||
}
|
}
|
||||||
a = a.FieldByIndex(sf.Index)
|
a = a.FieldByIndex(sf.Index)
|
||||||
b = b.FieldByIndex(sf.Index)
|
b = b.FieldByIndex(sf.Index)
|
||||||
return less(a, b)
|
return compare(a, b)
|
||||||
})
|
})
|
||||||
|
|
||||||
if sortType[0] == "desc" {
|
|
||||||
reverseSlice(slice)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo remove after migration
|
|
||||||
func reverseSlice(slice interface{}) {
|
|
||||||
sv := sliceValue(slice)
|
|
||||||
swp := reflect.Swapper(sv.Interface())
|
|
||||||
for i, j := 0, sv.Len()-1; i < j; i, j = i+1, j-1 {
|
|
||||||
swp(i, j)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Without creates a slice excluding all given values
|
// Without creates a slice excluding all given values
|
||||||
func Without[T comparable](slice []T, values ...T) []T {
|
func Without[T comparable](slice []T, values ...T) []T {
|
||||||
if len(values) == 0 || len(slice) == 0 {
|
if len(values) == 0 || len(slice) == 0 {
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ func TestDifference(t *testing.T) {
|
|||||||
assert.Equal([]int{1, 2, 3}, Difference(s1, s2))
|
assert.Equal([]int{1, 2, 3}, Difference(s1, s2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSortByField(t *testing.T) {
|
func TestSortByFieldDesc(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestSortByField")
|
assert := internal.NewAssert(t, "TestSortByField")
|
||||||
|
|
||||||
type student struct {
|
type student struct {
|
||||||
@@ -406,6 +406,31 @@ func TestSortByField(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(students, studentsOfSortByAge)
|
assert.Equal(students, studentsOfSortByAge)
|
||||||
}
|
}
|
||||||
|
func TestSortByFieldAsc(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSortByField")
|
||||||
|
|
||||||
|
type student struct {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
}
|
||||||
|
students := []student{
|
||||||
|
{"a", 10},
|
||||||
|
{"b", 15},
|
||||||
|
{"c", 5},
|
||||||
|
{"d", 6},
|
||||||
|
}
|
||||||
|
studentsOfSortByAge := []student{
|
||||||
|
{"c", 5},
|
||||||
|
{"d", 6},
|
||||||
|
{"a", 10},
|
||||||
|
{"b", 15},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := SortByField(students, "age")
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
assert.Equal(students, studentsOfSortByAge)
|
||||||
|
}
|
||||||
|
|
||||||
func TestWithout(t *testing.T) {
|
func TestWithout(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TestWithout")
|
assert := internal.NewAssert(t, "TestWithout")
|
||||||
|
|||||||
Reference in New Issue
Block a user