// Adjacent invocations on the same receiver with the same paramsKey will return a cached result.
//
// This may safely be executed in parallel.
-
func (p Pages) ByParam(paramsKey interface{}) Pages {
paramsKeyStr := cast.ToString(paramsKey)
key := "pageSort.ByParam." + paramsKeyStr
paramsKeyComparator := func(p1, p2 *Page) bool {
v1, _ := p1.Param(paramsKeyStr)
v2, _ := p2.Param(paramsKeyStr)
- s1 := cast.ToString(v1)
- s2 := cast.ToString(v2)
- // Sort nils last.
- if s1 == "" {
+ if v1 == nil {
return false
- } else if s2 == "" {
+ }
+
+ if v2 == nil {
return true
}
+ isNumeric := func(v interface{}) bool {
+ switch v.(type) {
+ case uint8, uint16, uint32, uint64, int, int8, int16, int32, int64, float32, float64:
+ return true
+ default:
+ return false
+ }
+ }
+
+ if isNumeric(v1) && isNumeric(v2) {
+ return cast.ToFloat64(v1) < cast.ToFloat64(v2)
+ }
+
+ s1 := cast.ToString(v1)
+ s2 := cast.ToString(v2)
+
return s1 < s2
}
assert.Equal(t, unsetValue, unsetSortedValue)
}
+func TestPageSortByParamNumeric(t *testing.T) {
+ t.Parallel()
+ var k interface{} = "arbitrarily.nested"
+ s := newTestSite(t)
+
+ n := 10
+ unsorted := createSortTestPages(s, n)
+ for i := 0; i < n; i++ {
+ v := 100 - i
+ if i%2 == 0 {
+ v = 100.0 - i
+ }
+
+ unsorted[i].params = map[string]interface{}{
+ "arbitrarily": map[string]interface{}{
+ "nested": v,
+ },
+ }
+ }
+ delete(unsorted[9].params, "arbitrarily")
+
+ firstSetValue, _ := unsorted[0].Param(k)
+ secondSetValue, _ := unsorted[1].Param(k)
+ lastSetValue, _ := unsorted[8].Param(k)
+ unsetValue, _ := unsorted[9].Param(k)
+
+ assert.Equal(t, 100, firstSetValue)
+ assert.Equal(t, 99, secondSetValue)
+ assert.Equal(t, 92, lastSetValue)
+ assert.Equal(t, nil, unsetValue)
+
+ sorted := unsorted.ByParam("arbitrarily.nested")
+ firstSetSortedValue, _ := sorted[0].Param(k)
+ secondSetSortedValue, _ := sorted[1].Param(k)
+ lastSetSortedValue, _ := sorted[8].Param(k)
+ unsetSortedValue, _ := sorted[9].Param(k)
+
+ assert.Equal(t, 92, firstSetSortedValue)
+ assert.Equal(t, 93, secondSetSortedValue)
+ assert.Equal(t, 100, lastSetSortedValue)
+ assert.Equal(t, unsetValue, unsetSortedValue)
+}
+
func BenchmarkSortByWeightAndReverse(b *testing.B) {
s := newTestSite(b)
p := createSortTestPages(s, 300)