'iterate through complex nested json array javascript
Json Structure:
{
"id": "30080",
"dataelements": {
"Name": "abc",
},
"children": [
{
"id": "33024",
"dataelements": {
"Name": "a",
},
"children": [
{
"id": "33024",
"dataelements": {
"Name": "b"
},
"children": [
{
"id": "33024",
"dataelements": {
"Name": "z"
},
"children": []
}
]
}
]
},
{
"id": "4800",
"dataelements": {
"Name": "d"
},
"children": [
{
"id": "4800",
"dataelements": {
.........................
I have my nested json data as shown in the image. For every child object, I create a node model. A child object can have additional child objects inside it.
if (ele == "dataelements")
{
var categoryNode = new NodeModel(
{
label: row.dataelements.Name,
icons: [{ iconName: 'product'}],
grid: row[ele]
});
}
if(ele == "children")
{
var subCategoryNode;
var subCategoryIndex = 1;
for (var i = 0, len = row.children.length; i<len; i++)
{
subCategoryNode = new NodeModel(
{
label: row.children[i].dataelements.Name,
icons: [{
iconName: '3dpart' }],
grid: row.children[i].dataelements
});
categoryNode.addChild(subCategoryNode);
}
}
This code handles only one level of child nodes. How do I check for the inner children when I don't know exactly how many child levels are nested inside?
Solution 1:[1]
A quick run down on recursive functions and a gotcha to look out for
- Recursive functions are great for nested data
- They call themselves for each iteration of the input until it hits a base case
- They can be tricky to wrap your head around at first
- Recursive functions can hit the call stack limit if used poorly or the input is monstrous in size
- Look out for variables used in the recursive calls, use let keyword to tell javascript to set the variable in the current scope
The Solution
Let's assume your JSON has been validated and this is the structure in the example below. If I want to iterate through all elements in the JSON, I want to use a recursive call to make it neat, and simple to debug and simple to build on.
Here is an example of iterating through your given example JSON to print out an exploded view.
How to use the below code
- Copy the recursiveSearch function
- Call the recursiveSearch function passing in your JSON
- Modify it to your needs, I gave you something to build on
CODE
var someJson = {"id": "30080","dataelements": {"Name": "abc"},"children": [{"id": "33024","dataelements": {"Name": "a"},"children": [{"id": "33024","dataelements": {"Name": "b"},"children": [{"id": "33024","dataelements": {"Name": "z"},"children": []}]}]}, {"id": "4800","dataelements": {"Name": "d"},"children": []}]};
//we set level to 0 (optional variable) this means we can omit it in the inital call for neat code
function recursiveScan(json, level=0)
{
//we store all of the output in a log and keep a track of the level to determine indenting
var log = "";
var indent = "";
//based on the current level of the recursion, we indent the text to make it readable
for (let i=0; i<level; i++)
{
indent += "  ";
}
//avoid any bad json or invalid data by checking if the name and id is null
if(json.dataelements.Name != null && json.id != null)
{
//we know there is a valid element, write the name and id
log += indent + "ID: " + json.id + "<br>";
log += indent + "Name: " + json.dataelements.Name + "<br>";
//if there is any children
if(json.children.length > 0)
{
//just for neatness, lets draw the paranthesis
log += indent + "{" + "<br>";
//increase the level
level++;
//for each child, recursively call this function to get the next level of children if available
for(let t=0; t<json.children.length; t++)
{
log += recursiveScan(json.children[t], level);
}
//we are dropping our recursion level now, getting ready to return;
level--;
//close the paranthesis for neatness
log += indent + "}" + "<br>";
}
}
//return the final log
return log;
}
//now lets test the code
document.write(recursiveScan(someJson));
The above code produces
ID: 30080
Name: abc
{
??ID: 33024
??Name: a
??{
????ID: 33024
????Name: b
????{
??????ID: 33024
??????Name: z
????}
??}
??ID: 4800
??Name: d
}
Now a simple run-down without all the noise
function recursiveScan(json)
{
if(json.dataelements.Name != null && json.id != null)
{
//here you have access to id and dataelements
if(json.children.length > 0)
{
for(let t=0; t<json.children.length; t++)
{
//here you have access to each child as json.children[t]
//you could do the logic for the current child
//then pass the current child to the recursive function
recursiveScan(json.children[t]);
}
}
}
return true;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |