-
Notifications
You must be signed in to change notification settings - Fork 612
Sorting, reversing and reverse sorting #353
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
@gamma sorry for the delay, that looks nice and might be helpful, would you mind adding tests ? |
Sure should 😄 |
👍 Do you mind if I add test myself if I find the time at some point ? |
Absolutely not. Please go ahead 🙏 |
@gamma I'll probably go in a slightly different direction for type sortable interface {
sort.Interface
set(string, interface{}) error
get() []interface{}
}
type sortableData struct {
data []interface{}
}
func (s sortableData) get() []interface{} {
return s.data
}
// method required to implement sort.Interface
func (s sortableData) Len() int { return len(s.data) }
// method required to implement sort.Interface
func (s sortableData) Swap(i, j int) { s.data[i], s.data[j] = s.data[j], s.data[i] }
type sortableByKey struct {
sortableData
key string
}
func (s *sortableByKey) set(funcName string, entries interface{}) (err error) {
entriesVal, err := getArrayValues(funcName, entries)
if err != nil {
return
}
s.data = make([]interface{}, entriesVal.Len())
for i := 0; i < entriesVal.Len(); i++ {
s.data[i] = reflect.Indirect(entriesVal.Index(i)).Interface()
}
return
}
// method required to implement sort.Interface
func (s sortableByKey) Less(i, j int) bool {
values := map[int]string{i: "", j: ""}
for k := range values {
if v := reflect.ValueOf(deepGet(s.data[k], s.key)); v.Kind() != reflect.Invalid {
values[k] = v.Interface().(string)
}
}
return values[i] < values[j]
}
// Generalized SortBy function
func generalizedSortBy(funcName string, entries interface{}, s sortable, reverse bool) (sorted []interface{}, err error) {
err = s.set(funcName, entries)
if err != nil {
return nil, err
}
if reverse {
sort.Stable(sort.Reverse(s))
} else {
sort.Stable(s)
}
return s.get(), nil
}
// sortObjectsByKeysAsc returns a sorted array of objects, sorted by object's key field in ascending order
func sortObjectsByKeysAsc(objs interface{}, key string) ([]interface{}, error) {
s := &sortableByKey{key: key}
return generalizedSortBy("sortObjsByKeys", objs, s, false)
}
// sortObjectsByKeysDesc returns a sorted array of objects, sorted by object's key field in descending order
func sortObjectsByKeysDesc(objs interface{}, key string) ([]interface{}, error) {
s := &sortableByKey{key: key}
return generalizedSortBy("sortObjsByKey", objs, s, true)
} The idea is to be be able to
also this check if v := reflect.ValueOf(deepGet(s.data[k], s.key)); v.Kind() != reflect.Invalid {
values[k] = v.Interface().(string)
} Is needed because I think I'll probably open another PR and co-author the commit with you if that's ok with you. |
Absolutely. Honestly I'm not at all into Go - I just put together what I thought would be working and it was OK for my case. Please feel free to take this direction - it makes sense for future extensions. |
superseded by #382 |
The PR adds sorting, reversing and reverse sorting of object lists. I was using these function in my fork for some time, since docker-gen looked stale some time ago. Would be nice to add these functions.
@buchdag can you please have a look at it?