@@ -29,52 +29,84 @@ func exists(path string) (bool, error) {
29
29
return false , err
30
30
}
31
31
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 )
41
34
42
- }
35
+ kind := entriesVal .Kind ()
36
+
37
+ if kind == reflect .Ptr {
38
+ entriesVal = reflect .Indirect (entriesVal )
39
+ kind = entriesVal .Kind ()
43
40
}
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
45
49
}
46
50
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 )
52
63
if value != nil {
53
- groups [ value .( string )] = append ( groups [ value .( string )] , v )
64
+ addEntry ( groups , value , v )
54
65
}
55
66
}
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
+ })
57
84
}
58
85
59
86
// 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
+
62
96
ret := []string {}
63
- for k , _ := range groups {
97
+ for k := range keys {
64
98
ret = append (ret , k )
65
99
}
66
- return ret
100
+ return ret , nil
67
101
}
68
102
69
103
// Generalized where function
70
104
func generalizedWhere (funcName string , entries interface {}, key string , test func (interface {}) bool ) (interface {}, error ) {
71
- entriesVal := reflect .ValueOf (entries )
72
105
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
78
110
}
79
111
80
112
selection := make ([]interface {}, 0 )
0 commit comments