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
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": []
}
]
}
]
}
]
}
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
isTrue
the output should contain it’sorg_name
and it’sorgs
; - If
available
isFalse
then it should be removed; - If a child
org
has it’savailable
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
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": []
}
]
}
]
}
]
}