1
0
mirror of https://github.com/danog/liquid.git synced 2024-12-02 23:27:47 +01:00
liquid/values/sort.go

77 lines
1.6 KiB
Go
Raw Normal View History

2017-07-28 00:11:37 +02:00
package values
2017-06-27 16:28:39 +02:00
import (
"reflect"
"sort"
)
// Sort any []interface{} value.
func Sort(data []interface{}) {
sort.Sort(genericSortable(data))
}
2017-07-12 19:10:19 +02:00
type genericSortable []interface{}
2017-06-27 16:28:39 +02:00
// Len is part of sort.Interface.
func (s genericSortable) Len() int {
return len(s)
}
// Swap is part of sort.Interface.
func (s genericSortable) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Less is part of sort.Interface.
func (s genericSortable) Less(i, j int) bool {
2017-06-28 15:36:39 +02:00
return Less(s[i], s[j])
2017-06-27 16:28:39 +02:00
}
// SortByProperty sorts maps on their key indices.
func SortByProperty(data []interface{}, key string, nilFirst bool) {
sort.Sort(sortableByProperty{data, key, nilFirst})
2017-06-27 16:28:39 +02:00
}
type sortableByProperty struct {
data []interface{}
key string
nilFirst bool
2017-06-27 16:28:39 +02:00
}
// Len is part of sort.Interface.
func (s sortableByProperty) Len() int {
return len(s.data)
}
// Swap is part of sort.Interface.
func (s sortableByProperty) Swap(i, j int) {
data := s.data
data[i], data[j] = data[j], data[i]
}
// Less is part of sort.Interface.
func (s sortableByProperty) Less(i, j int) bool {
2017-07-21 22:26:04 +02:00
// index returns the value at s.key, if in is a map that contains this key
2017-06-28 03:30:47 +02:00
index := func(i int) interface{} {
2017-07-03 18:00:43 +02:00
value := ToLiquid(s.data[i])
2017-06-28 03:30:47 +02:00
rt := reflect.ValueOf(value)
2017-06-27 16:28:39 +02:00
if rt.Kind() == reflect.Map && rt.Type().Key().Kind() == reflect.String {
2017-06-28 03:30:47 +02:00
elem := rt.MapIndex(reflect.ValueOf(s.key))
if elem.IsValid() {
return elem.Interface()
}
2017-06-27 16:28:39 +02:00
}
return nil
}
2017-06-28 03:30:47 +02:00
a, b := index(i), index(j)
2017-06-28 15:36:39 +02:00
switch {
case a == nil && b == nil:
return false
case a == nil:
return s.nilFirst
2017-06-28 15:36:39 +02:00
case b == nil:
return !s.nilFirst
2017-06-28 15:36:39 +02:00
}
2017-06-28 03:30:47 +02:00
return Less(a, b)
2017-06-27 16:28:39 +02:00
}