Skip to content

Commit 4922c94

Browse files
committed
feat: support sorting dict
1 parent 6742af6 commit 4922c94

File tree

3 files changed

+58
-47
lines changed

3 files changed

+58
-47
lines changed

jsonpath/__init__.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Author : zhangxianbing1
33
Date : 2020-12-27 09:22:14
44
LastEditors : zhangxianbing1
5-
LastEditTime : 2021-01-04 10:27:22
5+
LastEditTime : 2021-01-04 10:50:28
66
Description : JSONPath
77
"""
88
__version__ = "0.0.2"
@@ -212,20 +212,28 @@ def _trace(self, obj, i: int):
212212
# sort
213213
if step.startswith("/(") and step.endswith(")"):
214214
if isinstance(obj, list):
215-
step = step[2:-1]
216-
for sortby in step.split(",")[::-1]:
215+
for sortby in step[2:-1].split(",")[::-1]:
217216
if sortby.startswith("~"):
218217
obj.sort(
219218
key=lambda t, k=sortby: _getattr(t, k[1:]), reverse=True
220219
)
221220
else:
222221
obj.sort(key=lambda t, k=sortby: _getattr(t, k))
223-
222+
elif isinstance(obj, dict):
223+
obj = [(k, v) for k, v in obj.items()]
224+
for sortby in step[2:-1].split(",")[::-1]:
225+
if sortby.startswith("~"):
226+
obj.sort(
227+
key=lambda t, k=sortby: _getattr(t[1], k[1:]), reverse=True
228+
)
229+
else:
230+
obj.sort(key=lambda t, k=sortby: _getattr(t[1], k))
231+
obj = {k: v for k, v in obj}
224232
self._traverse(self._trace, obj, i + 1)
225233
return
226234

227235

228236
if __name__ == "__main__":
229237
with open("test/data/2.json", "rb") as f:
230238
d = json.load(f)
231-
JSONPath("$.book[/(price)].price").parse(d)
239+
JSONPath("$.scores[/(score)].score").parse(d)

test/conftest.py

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,12 @@
1-
import pytest
1+
import json
22
from collections import namedtuple
33

4+
import pytest
5+
46
TestCase = namedtuple("TestCase", ("expr", "data", "result"))
57

6-
data = {
7-
"a.b c": "a.b c",
8-
"book": [
9-
{
10-
"category": "reference",
11-
"author": "Nigel Rees",
12-
"title": "Sayings of the Century",
13-
"price": 8.95,
14-
"brand": {"version": "v1.0.0"},
15-
},
16-
{
17-
"category": "fiction",
18-
"author": "Evelyn Waugh",
19-
"title": "Sword of Honour",
20-
"price": 12.99,
21-
"brand": {"version": "v0.0.1"},
22-
},
23-
{
24-
"category": "fiction",
25-
"author": "Herman Melville",
26-
"title": "Moby Dick",
27-
"isbn": "0-553-21311-3",
28-
"price": 8.99,
29-
"brand": {"version": "v1.0.2"},
30-
},
31-
{
32-
"category": "fiction",
33-
"author": "J. R. R. Tolkien",
34-
"title": "The Lord of the Rings",
35-
"isbn": "0-395-19395-8",
36-
"price": 22.99,
37-
"brand": {"version": "v1.0.3"},
38-
},
39-
],
40-
"bicycle": {"color": "red", "price": 19.95},
41-
}
8+
with open("test/data/2.json", "rb") as f:
9+
data = json.load(f)
4210

4311

4412
@pytest.fixture(
@@ -75,6 +43,7 @@
7543
data,
7644
["v0.0.1", "v1.0.0", "v1.0.2", "v1.0.3"],
7745
),
46+
TestCase("$.scores[/(score)].score", data, [60, 85, 90, 95, 100]),
7847
]
7948
)
8049
def cases(request):

test/data/2.json

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,69 @@
11
{
2-
"foo.bar": "foo.bar",
2+
"a.b c": "a.b c",
33
"book": [
44
{
55
"category": "reference",
66
"author": "Nigel Rees",
77
"title": "Sayings of the Century",
8-
"price": 8.95
8+
"price": 8.95,
9+
"brand": {
10+
"version": "v1.0.0"
11+
}
912
},
1013
{
1114
"category": "fiction",
1215
"author": "Evelyn Waugh",
1316
"title": "Sword of Honour",
14-
"price": 12.99
17+
"price": 12.99,
18+
"brand": {
19+
"version": "v0.0.1"
20+
}
1521
},
1622
{
1723
"category": "fiction",
1824
"author": "Herman Melville",
1925
"title": "Moby Dick",
2026
"isbn": "0-553-21311-3",
21-
"price": 8.99
27+
"price": 8.99,
28+
"brand": {
29+
"version": "v1.0.2"
30+
}
2231
},
2332
{
2433
"category": "fiction",
2534
"author": "J. R. R. Tolkien",
2635
"title": "The Lord of the Rings",
2736
"isbn": "0-395-19395-8",
28-
"price": 22.99
37+
"price": 22.99,
38+
"brand": {
39+
"version": "v1.0.3"
40+
}
2941
}
3042
],
3143
"bicycle": {
3244
"color": "red",
3345
"price": 19.95
46+
},
47+
"scores": {
48+
"math": {
49+
"score": 100,
50+
"avg": 60
51+
},
52+
"english": {
53+
"score": 95,
54+
"avg": 80
55+
},
56+
"physic": {
57+
"score": 90,
58+
"avg": 70
59+
},
60+
"chemistry": {
61+
"score": 85,
62+
"avg": 80
63+
},
64+
"chinese": {
65+
"score": 60,
66+
"avg": 75
67+
}
3468
}
3569
}

0 commit comments

Comments
 (0)