Reading a json object and removing some values

Question:

I have a JSON object with following structure:

{
    "org_name": "1",
    "available": True,
    "orgs": [
        {
            "org_name": "2",
            "available": False,
            "orgs": []
        },
        {
            "org_name": "3",
            "available": False,
            "orgs": []
        },
        {
            "org_name": "4",
            "available": True,
            "orgs": []
        },
        {
            "org_name": "5",
            "available": False,
            "orgs": [
                {
                    "org_name": "6",
                    "available": False,
                    "orgs": []
                },
                {
                    "org_name": "7",
                    "available": False,
                    "orgs": []
                },
                {
                    "org_name": "8",
                    "available": False,
                    "orgs": [
                        {
                            "org_name": "9",
                            "available": False,
                            "orgs": []
                        },
                        {
                            "org_name": "10",
                            "available": True,
                            "orgs": []
                        }
                    ]
                }
            ]
        }
    ]
}

I want to parse this JSON data and get a output similar to this:

{
  "org_name": "1",
  "orgs": [
    {
      "org_name": "4",
      "orgs": []
    },
    {
      "org_name": "5",
      "orgs": [
        {
          "org_name":"8",
           "orgs":[
           {
           "org_name":"10"
           }
         ]
        }
      ]
    }
}

The conditions are:

  • If available is True the output should contain it’s org_name and it’s orgs;
  • If available is False then it should be removed;
  • If a child org has it’s available True than full parent org should be present.

I am having a hard time finding a logic to get a output.

Any help is appreciated

Asked By: Tony Frank

||

Answers:

You need to write simple recursive function which will check your JSON object if it’s available or any of it’s child nodes is available:

def filter_orgs(source):
    orgs = [org for o in source["orgs"] if (org := filter_orgs(o))]
    if orgs or source["available"]:
        return {
            "org_name": source["org_name"], 
            "orgs": orgs
        }

Usage:

source = {
    "org_name": "1",
    "available": True,
    "orgs": [
        {
            "org_name": "2",
            "available": False,
            "orgs": []
        },
        {
            "org_name": "3",
            "available": False,
            "orgs": []
        },
        {
            "org_name": "4",
            "available": True,
            "orgs": []
        },
        {
            "org_name": "5",
            "available": False,
            "orgs": [
                {
                    "org_name": "6",
                    "available": False,
                    "orgs": []
                },
                {
                    "org_name": "7",
                    "available": False,
                    "orgs": []
                },
                {
                    "org_name": "8",
                    "available": False,
                    "orgs": [
                        {
                            "org_name": "9",
                            "available": False,
                            "orgs": []
                        },
                        {
                            "org_name": "10",
                            "available": True,
                            "orgs": []
                        }
                    ]
                }
            ]
        }
    ]
}

filtered_source = filter_orgs(source)

Output:

{
    "org_name": "1",
    "orgs": [
        {
            "org_name": "4",
            "orgs": []
        },
        {
            "org_name": "5",
            "orgs": [
                {
                    "org_name": "8",
                    "orgs": [
                        {
                            "org_name": "10",
                            "orgs": []
                        }
                    ]
                }
            ]
        }
    ]
}

Upd. You can also implement in-place modification of dictionary:

def filter_orgs_inplace(source):
    available = source.pop("available")
    for i in range(len(orgs := source["orgs"]) - 1, -1, -1):
        if not filter_orgs_inplace(orgs[i]):
            del orgs[i]
        else:
            available = True
    if not available:
        source.clear()
    return available

Usage:

source = {
    "org_name": "1",
    "available": True,
    "orgs": [
        {
            "org_name": "2",
            "available": False,
            "orgs": []
        },
        {
            "org_name": "3",
            "available": False,
            "orgs": []
        },
        {
            "org_name": "4",
            "available": True,
            "orgs": []
        },
        {
            "org_name": "5",
            "available": False,
            "orgs": [
                {
                    "org_name": "6",
                    "available": False,
                    "orgs": []
                },
                {
                    "org_name": "7",
                    "available": False,
                    "orgs": []
                },
                {
                    "org_name": "8",
                    "available": False,
                    "orgs": [
                        {
                            "org_name": "9",
                            "available": False,
                            "orgs": []
                        },
                        {
                            "org_name": "10",
                            "available": True,
                            "orgs": []
                        }
                    ]
                }
            ]
        }
    ]
}

filter_orgs_inplace(source)  # modifies source

Output:

{
    "org_name": "1",
    "orgs": [
        {
            "org_name": "4",
            "orgs": []
        },
        {
            "org_name": "5",
            "orgs": [
                {
                    "org_name": "8",
                    "orgs": [
                        {
                            "org_name": "10",
                            "orgs": []
                        }
                    ]
                }
            ]
        }
    ]
}
Answered By: Olvin Roght
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.