Skip to content

Commit 827ac0d

Browse files
authored
Merge pull request #3 from jmespath-community/jep/grouping
JEP-18 Grouping
2 parents e62713d + 882c00c commit 827ac0d

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

jmespath/functions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import math
22
import json
33

4+
from collections import OrderedDict
5+
46
from jmespath import exceptions
57
from jmespath.compat import get_methods
68
from jmespath.compat import iteritems
@@ -533,6 +535,19 @@ def _func_max_by(self, array, expref):
533535
def _func_zip(self, *arguments):
534536
return list(map(list, zip(*arguments)))
535537

538+
@signature({'types': ['array']}, {'types': ['expref']})
539+
def _func_group_by(self, array, expref):
540+
keyfunc = self._create_key_func(expref, ['null', 'string'], 'group_by')
541+
if array:
542+
result = OrderedDict()
543+
keys = list(dict.fromkeys([keyfunc(item) for item in array if keyfunc(item) != None]))
544+
for key in keys:
545+
items = [ item for item in array if keyfunc(item) == key ]
546+
result.update({key: items})
547+
return result
548+
else:
549+
return None
550+
536551
def _create_key_func(self, expref, allowed_types, function_name):
537552
def keyfunc(x):
538553
result = expref.visit(expref.expression, x)
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
[
2+
{
3+
"given": {
4+
"items": [
5+
{
6+
"spec": {
7+
"nodeNumber": 1,
8+
"nodeName": "node_01",
9+
"other": "values_01"
10+
}
11+
},
12+
{
13+
"spec": {
14+
"nodeNumber": 2,
15+
"nodeName": "node_02",
16+
"other": "values_02"
17+
}
18+
},
19+
{
20+
"spec": {
21+
"nodeNumber": 3,
22+
"nodeName": "node_03",
23+
"other": "values_03"
24+
}
25+
},
26+
{
27+
"spec": {
28+
"nodeNumber": 1,
29+
"nodeName": "node_01",
30+
"other": "values_04"
31+
}
32+
}
33+
]
34+
},
35+
"cases": [
36+
{
37+
"expression": "group_by(@, &`false`)",
38+
"error": "invalid-type"
39+
},
40+
{
41+
"expression": "group_by(keys(items[*].spec|[0]), &`false`)",
42+
"error": "invalid-type"
43+
},
44+
{
45+
"expression": "group_by(items, spec.nodeName)",
46+
"error": "invalid-type"
47+
},
48+
{
49+
"expression": "group_by(items, &spec.nodeName)",
50+
"result": {
51+
"node_01": [
52+
{
53+
"spec": {
54+
"nodeNumber": 1,
55+
"nodeName": "node_01",
56+
"other": "values_01"
57+
}
58+
},
59+
{
60+
"spec": {
61+
"nodeNumber": 1,
62+
"nodeName": "node_01",
63+
"other": "values_04"
64+
}
65+
}
66+
],
67+
"node_02": [
68+
{
69+
"spec": {
70+
"nodeNumber": 2,
71+
"nodeName": "node_02",
72+
"other": "values_02"
73+
}
74+
}
75+
],
76+
"node_03": [
77+
{
78+
"spec": {
79+
"nodeNumber": 3,
80+
"nodeName": "node_03",
81+
"other": "values_03"
82+
}
83+
}
84+
]
85+
}
86+
},
87+
{
88+
"expression": "group_by(items, &to_string(spec.nodeNumber))",
89+
"result": {
90+
"1": [
91+
{
92+
"spec": {
93+
"nodeNumber": 1,
94+
"nodeName": "node_01",
95+
"other": "values_01"
96+
}
97+
},
98+
{
99+
"spec": {
100+
"nodeNumber": 1,
101+
"nodeName": "node_01",
102+
"other": "values_04"
103+
}
104+
}
105+
],
106+
"2": [
107+
{
108+
"spec": {
109+
"nodeNumber": 2,
110+
"nodeName": "node_02",
111+
"other": "values_02"
112+
}
113+
}
114+
],
115+
"3": [
116+
{
117+
"spec": {
118+
"nodeNumber": 3,
119+
"nodeName": "node_03",
120+
"other": "values_03"
121+
}
122+
}
123+
]
124+
}
125+
},
126+
{
127+
"expression": "group_by(items, &spec.nodeNumber)",
128+
"error": "invalid-type"
129+
}
130+
]
131+
}
132+
]

0 commit comments

Comments
 (0)