Bad JSON for custom JSON

I'm currently trying to massage the unwanted JSON output, which I am returning to a format that is more valuable to me. The answers should use jq or Python code (I am using the pyjq library in python)

Here is the current JSON output:

[
 {"colour":"Red", "car": [ {"year":2000, "make":"Honda", "model":"Accord"} ] },
 {"colour":"Blue", "car": [ {"year":2015, "make":"Toyota", "model":"Camry"} ] },
 {"colour":"Red", "car": [ {"year":1999, "make":"Dodge", "model":"Ram"} ] }
]

Using jq or perhaps a loop using Python, I would like to format it in a new JSON object that looks like this:

[
 { "Red":[2000,1999] },
 { "Blue": 2015 }
]

Does anyone know how I can format any JSON that looks like the first snippet above and turn it into the desired result indicated in the second snippet.

+4
source share
3 answers

jq . , . -, . group_by() -, .

$ jq 'group_by(.colour)' input.json
[
    [
        {"car":[{"model":"Camry","make":"Toyota","year":2015}],"colour":"Blue"}
    ],
    [
        {"car":[{"model":"Accord","make":"Honda","year":2000}],"colour":"Red"},
        {"car":[{"model":"Ram",   "make":"Dodge","year":1999}],"colour":"Red"}
    ]
]

- {color: [years]}. map() . {color: [years]} , .

. , .

$ jq -c 'group_by(.colour) | map({(.[0].colour): []})' input.json
[{"Blue":[]},{"Red":[]}]

Perfect. . , , map, .

$ jq -c 'group_by(.colour) | map({(.[0].colour): map(.car[].year)})' input.json
[{"Blue":[2015]},{"Red":[2000,1999]}]
+2

, dict, :

:

output = {}
for datum in data:
    for car in datum['car']:
        output.setdefault(datum['colour'], []).append(car['year'])

:

data = [
    {"colour": "Red",
     "car": [{"year": 2000, "make": "Honda", "model": "Accord"}]},
    {"colour": "Blue",
     "car": [{"year": 2015, "make": "Toyota", "model": "Camry"}]},
    {"colour": "Red",
     "car": [{"year": 1999, "make": "Dodge", "model": "Ram"}]}
]

output = {}
for datum in data:
    for car in datum['car']:
        output.setdefault(datum['colour'], []).append(car['year'])
print(output)

:

{'Red': [2000, 1999], 'Blue': [2015]}
+6

group_byincludes sorting and, therefore, is excessively inefficient for this problem. Here is a direct approach using jq. It looks like a python solution presented elsewhere on this page:

 reduce .[] as $car ({};
   .[ $car.colour ] += ($car.car | map(.year)) )
 | map_values(if length==1 then .[0] else . end)
 | [ to_entries[] | {(.key): .value} ]

A line starting with map_valuesmatches the requirements that single arrays need to avoid. The last line may be omitted if the result dictionary is acceptable.

Please note that the above program will work even if the array .carhas more than one element.

0
source

Source: https://habr.com/ru/post/1693171/


All Articles