From f147f78a41117a3c5b95de2690efad85173d3c77 Mon Sep 17 00:00:00 2001 From: donutloop Date: Tue, 11 Jan 2022 13:13:25 +0100 Subject: [PATCH] Slice: sort from v2 branch (#22) ref: https://github.com/duke-git/lancet/commit/f1d7154179a4d94472bee9703097d78e6c37e9a7 --- slice/slice.go | 37 +++++++++++++++++++++++++++---------- slice/slice_test.go | 28 +++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/slice/slice.go b/slice/slice.go index 8df6748..da07554 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -675,18 +675,38 @@ func SortByField(slice interface{}, field string, sortType ...string) error { } // 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() { 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: - 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: - 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: - 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: - 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: return fmt.Errorf("field type %s not supported", sf.Type) } @@ -700,12 +720,9 @@ func SortByField(slice interface{}, field string, sortType ...string) error { } a = a.FieldByIndex(sf.Index) b = b.FieldByIndex(sf.Index) - return less(a, b) + return compare(a, b) }) - if sortType[0] == "desc" { - ReverseSlice(slice) - } return nil } diff --git a/slice/slice_test.go b/slice/slice_test.go index d3f402e..9a7d6d2 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -443,7 +443,7 @@ func TestDifference(t *testing.T) { assert.Equal([]int{1, 2, 3}, Difference(s1, s2)) } -func TestSortByField(t *testing.T) { +func TestSortByFielDesc(t *testing.T) { assert := internal.NewAssert(t, "TestWithout") type student struct { @@ -469,6 +469,32 @@ func TestSortByField(t *testing.T) { 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) { assert := internal.NewAssert(t, "TestWithout") assert.Equal([]int{3, 4, 5}, Without([]int{1, 2, 3, 4, 5}, 1, 2))