@@ -29,52 +29,84 @@ func exists(path string) (bool, error) {
2929 return false , err
3030}
3131
32- func groupByMulti (entries []* RuntimeContainer , key , sep string ) map [string ][]* RuntimeContainer {
33- groups := make (map [string ][]* RuntimeContainer )
34- for _ , v := range entries {
35- value := deepGet (* v , key )
36- if value != nil {
37- items := strings .Split (value .(string ), sep )
38- for _ , item := range items {
39- groups [item ] = append (groups [item ], v )
40- }
32+ func getArrayValues (funcName string , entries interface {}) (reflect.Value , error ) {
33+ entriesVal := reflect .ValueOf (entries )
4134
42- }
35+ kind := entriesVal .Kind ()
36+
37+ if kind == reflect .Ptr {
38+ entriesVal = reflect .Indirect (entriesVal )
39+ kind = entriesVal .Kind ()
4340 }
44- return groups
41+
42+ switch entriesVal .Kind () {
43+ case reflect .Array , reflect .Slice :
44+ break
45+ default :
46+ return entriesVal , fmt .Errorf ("Must pass an array or slice to '%v'; received %v; kind %v" , funcName , entries , kind )
47+ }
48+ return entriesVal , nil
4549}
4650
47- // groupBy groups a list of *RuntimeContainers by the path property key
48- func groupBy (entries []* RuntimeContainer , key string ) map [string ][]* RuntimeContainer {
49- groups := make (map [string ][]* RuntimeContainer )
50- for _ , v := range entries {
51- value := deepGet (* v , key )
51+ // Generalized groupBy function
52+ func generalizedGroupBy (funcName string , entries interface {}, key string , addEntry func (map [string ][]interface {}, interface {}, interface {})) (map [string ][]interface {}, error ) {
53+ entriesVal , err := getArrayValues (funcName , entries )
54+
55+ if err != nil {
56+ return nil , err
57+ }
58+
59+ groups := make (map [string ][]interface {})
60+ for i := 0 ; i < entriesVal .Len (); i ++ {
61+ v := reflect .Indirect (entriesVal .Index (i )).Interface ()
62+ value := deepGet (v , key )
5263 if value != nil {
53- groups [ value .( string )] = append ( groups [ value .( string )] , v )
64+ addEntry ( groups , value , v )
5465 }
5566 }
56- return groups
67+ return groups , nil
68+ }
69+
70+ func groupByMulti (entries interface {}, key , sep string ) (map [string ][]interface {}, error ) {
71+ return generalizedGroupBy ("groupByMulti" , entries , key , func (groups map [string ][]interface {}, value interface {}, v interface {}) {
72+ items := strings .Split (value .(string ), sep )
73+ for _ , item := range items {
74+ groups [item ] = append (groups [item ], v )
75+ }
76+ })
77+ }
78+
79+ // groupBy groups a generic array or slice by the path property key
80+ func groupBy (entries interface {}, key string ) (map [string ][]interface {}, error ) {
81+ return generalizedGroupBy ("groupBy" , entries , key , func (groups map [string ][]interface {}, value interface {}, v interface {}) {
82+ groups [value .(string )] = append (groups [value .(string )], v )
83+ })
5784}
5885
5986// groupByKeys is the same as groupBy but only returns a list of keys
60- func groupByKeys (entries []* RuntimeContainer , key string ) []string {
61- groups := groupBy (entries , key )
87+ func groupByKeys (entries interface {}, key string ) ([]string , error ) {
88+ keys , err := generalizedGroupBy ("groupByKeys" , entries , key , func (groups map [string ][]interface {}, value interface {}, v interface {}) {
89+ groups [value .(string )] = append (groups [value .(string )], v )
90+ })
91+
92+ if err != nil {
93+ return nil , err
94+ }
95+
6296 ret := []string {}
63- for k , _ := range groups {
97+ for k := range keys {
6498 ret = append (ret , k )
6599 }
66- return ret
100+ return ret , nil
67101}
68102
69103// Generalized where function
70104func generalizedWhere (funcName string , entries interface {}, key string , test func (interface {}) bool ) (interface {}, error ) {
71- entriesVal := reflect .ValueOf (entries )
72105
73- switch entriesVal .Kind () {
74- case reflect .Array , reflect .Slice :
75- break
76- default :
77- return nil , fmt .Errorf ("Must pass an array or slice to '%s'; received %v" , funcName , entries )
106+ entriesVal , err := getArrayValues (funcName , entries )
107+
108+ if err != nil {
109+ return nil , err
78110 }
79111
80112 selection := make ([]interface {}, 0 )
0 commit comments