0

I have a nested json with an arbitrary depth level :

json_list = [
    { 
        'class': 'Year 1', 
        'room': 'Yellow',
        'students': [
            {'name': 'James', 'sex': 'M', 'grades': {}},
        ]
    },
    { 
        'class': 'Year 2',
        'info': {
            'teachers': { 
                'math': 'Alan Turing', 
                'physics': []
            }
        },
        'students': [
            { 'name': 'Tony', 'sex': 'M', 'age': ''},
            { 'name': 'Jacqueline', 'sex': 'F' },
        ],
        'other': []
    }
]

I want to remove any element that its value meet certain criteria.

For example:

values_to_drop = ({}, (), [], '', ' ')
filtered_json = clean_json(json_list, values_to_drop)
filtered_json

Expected Output of clean_json:

[
    { 
        'class': 'Year 1', 
        'room': 'Yellow',
        'students': [
            {'name': 'James', 'sex': 'M'},
        ]
    },
    { 
        'class': 'Year 2',
        'info': {
            'teachers': { 
                'math': 'Alan Turing', 
            }
        },
        'students': [
            { 'name': 'Tony', 'sex': 'M'},
            { 'name': 'Jacqueline', 'sex': 'F'},
        ]
    }
]

I thought of something like first converting the object to string using json.dumps and then looking in the string and replacing each value that meets the criteria with some kind of flag to filter it after before reading it again with json.loads but I couldn't figure it out and I don't know if this is the way to go

abdelgha4
  • 351
  • 1
  • 16

1 Answers1

0

I managed to get the desired output by tweaking this answer a bit:

def clean_json(json_obj, values_to_drop):
    if isinstance(json_obj, dict):
        json_obj = {
            key: clean_json(value, values_to_drop) 
            for key, value in json_obj.items()
            if value not in values_to_drop}
    elif isinstance(json_obj, list):
        json_obj = [clean_json(item, values_to_drop)
                  for item in json_obj
                  if item not in values_to_drop]
    return json_obj
abdelgha4
  • 351
  • 1
  • 16