1
+ using DevLab . JmesPath . Utils ;
2
+ using Newtonsoft . Json . Linq ;
3
+ using System ;
4
+ using System . Collections . Generic ;
5
+ using System . Linq ;
6
+
7
+ namespace DevLab . JmesPath . Functions
8
+ {
9
+ public class GroupByFunction : ByFunction
10
+ {
11
+ public GroupByFunction ( )
12
+ : base ( "group_by" )
13
+ {
14
+ }
15
+
16
+ public override void Validate ( params JmesPathFunctionArgument [ ] args )
17
+ {
18
+ base . Validate ( args ) ;
19
+
20
+ System . Diagnostics . Debug . Assert ( args . Length == 2 ) ;
21
+ System . Diagnostics . Debug . Assert ( args [ 0 ] . IsToken ) ;
22
+ System . Diagnostics . Debug . Assert ( args [ 1 ] . IsExpressionType ) ;
23
+
24
+ var array = ( JArray ) args [ 0 ] . Token ;
25
+ if ( array . Any ( i => i . Type != JTokenType . Object ) )
26
+ throw new Exception ( $ "Error: invalid-type, function { Name } expects its first argument to be an array of objects.") ;
27
+ }
28
+ public override JToken Execute ( params JmesPathFunctionArgument [ ] args )
29
+ {
30
+ System . Diagnostics . Debug . Assert ( args . Length == 2 ) ;
31
+ System . Diagnostics . Debug . Assert ( args [ 0 ] . IsToken ) ;
32
+ System . Diagnostics . Debug . Assert ( args [ 1 ] . IsExpressionType ) ;
33
+
34
+ var array = ( JArray ) args [ 0 ] . Token ;
35
+ var expression = args [ 1 ] . Expression ;
36
+
37
+ var dictionary = new Dictionary < string , IList < JToken > > ( ) ;
38
+
39
+ foreach ( var element in array )
40
+ {
41
+ string key = "" ;
42
+
43
+ var token = expression . Transform ( element ) . AsJToken ( ) ;
44
+ if ( token != JTokens . Null )
45
+ {
46
+ var tokenType = token . GetTokenType ( ) ;
47
+ if ( tokenType != "string" )
48
+ throw new Exception ( $ "Error: invalid-type, function { Name } expects its second expression-type argument to evaluate to a 'string' value but received '{ tokenType } ' { token } instead.") ;
49
+
50
+ key = token . Value < string > ( ) ;
51
+ AddElement ( dictionary , key , element ) ;
52
+ }
53
+ }
54
+
55
+ var properties = dictionary . Select ( kvp => new JProperty ( kvp . Key , kvp . Value ) ) ;
56
+
57
+ return new JObject ( properties ) ;
58
+ }
59
+
60
+ private static void AddElement ( IDictionary < string , IList < JToken > > dictionary , string key , JToken element )
61
+ {
62
+ if ( ! dictionary . ContainsKey ( key ) )
63
+ dictionary [ key ] = new List < JToken > ( ) ;
64
+
65
+ dictionary [ key ] . Add ( element ) ;
66
+ }
67
+ }
68
+ }
0 commit comments