Recursively Looping Through an Object to Build a Property List

Recursively looping through an object to build a property list

I made a FIDDLE for you. I am storing a stack string and then output it, if the property is of primitive type:

function iterate(obj, stack) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
} else {
console.log(property + " " + obj[property]);
$('#output').append($("<div/>").text(stack + '.' + property))
}
}
}
}

iterate(object, '')


Update: 17/01/2019

There used to be a different implementation, but it didn't work. See
this answer
for a prettier solution

looping through an object (tree) recursively

You're looking for the for...in loop:

for (var key in foo)
{
if (key == "child")
// do something...
}

Be aware that for...in loops will iterate over any enumerable properties, including those that are added to the prototype of an object. To avoid acting on these properties, you can use the hasOwnProperty method to check to see if the property belongs only to that object:

for (var key in foo)
{
if (!foo.hasOwnProperty(key))
continue; // skip this property
if (key == "child")
// do something...
}

Performing the loop recursively can be as simple as writing a recursive function:

// This function handles arrays and objects
function eachRecursive(obj)
{
for (var k in obj)
{
if (typeof obj[k] == "object" && obj[k] !== null)
eachRecursive(obj[k]);
else
// do something...
}
}

Recursive loop through Javascript Object

You have a couple of issues; you should be traversing over the object, not its keys, and you should be checking if key === 'e', not target[key] !== 'e'. Also, you should check that target[key] is an object before attempting to traverse it:

const myObject = {
x: {
y: {
z: {
e: 'ddfg'
}
}
}
};

function traverse(target) {
for (const key in target) {
if (key !== 'e' && typeof target[key] === 'object') {
traverse(target[key]);
} else {
console.log(key, target[key]);
}
}
}

traverse(myObject);

Javascript: iterate through object with recursion to build navigation list

If you have control the structure of the navigation data, you can implement Nerdwood's answer.

But if you don't have the control, you can try:

Walker

function menuWalker(obj) {
var html = '<ul>';
for (var property in obj) {
if (obj.hasOwnProperty(property) && typeof obj[property] == "object") {
html += '<li>' + childrenMenuWalker(obj[property]) + '</li>';
}
}
html += '</ul>';
return html;
}

function childrenMenuWalker(obj) {
var html = '';
if (obj.hasOwnProperty('title') && obj.hasOwnProperty('link')) {
html += '<a href="' + obj.link + '">' + obj.title + '</a>';
}

var hasChildren = false;
var childrenHtml = '<ul>';
for (var property in obj) {
if (obj.hasOwnProperty(property) && typeof obj[property] == "object") {
hasChildren = true;
childrenHtml += '<li>' + childrenMenuWalker(obj[property]) + '</li>';
}
}
childrenHtml += '</ul>';

if (hasChildren) {
html += childrenHtml;
}

return html;
}

Recursively loop through objects of object

To achieve the result with a single push, one can pass the result table to the function when called recursively, but default it to an empty table on the first call. I've also changed .map to .forEach since the return value is not used:

const response = {
"data": {
"Cstm_PF_ADG_URT_Disposition": {
"child_welfare_placement_value": ""
},
"Cstm_PF_ADG_URT_Demographics": {
"school_grade": "family setting",
"school_grade_code": ""
},
"Cstm_Precert_Medical_Current_Meds": [
{
"med_name": "med1",
"dosage": "10mg",
"frequency": "daily"
},
{
"med_name": "med2",
"dosage": "20mg",
"frequency": "daily"
}
],
"Cstm_PF_ADG_URT_Substance_Use": {
"dimension1_comment": "dimension 1 - tab1",
"Textbox1": "text - tab1"
},
"Cstm_PF_ADG_Discharge_Note": {
"prior_auth_no_comm": "auth no - tab2"
},
"Cstm_PF_ADG_URT_Clinical_Plan": {
"cca_cs_dhs_details": "details - tab2"
},
"container": {
"Cstm_PF_Name": {
"first_name": "same text for textbox - footer",
"last_name": "second textbox - footer"
},
"Cstm_PF_ADG_URT_Demographics": {
"new_field": "mapped demo - footer"
},
"grid2": [
{
"Cstm_PF_ADG_COMP_Diagnosis": {
"diagnosis_label": "knee",
"diagnosis_group_code": "leg"
}
},
{
"Cstm_PF_ADG_COMP_Diagnosis": {
"diagnosis_label": "ankle",
"diagnosis_group_code": "leg"
}
}
]
},
"submit": true
}
};

function getNamesAndValues(data, id, tablesAndValues = []) {
const res = data;

Object.entries(res).forEach(([key, value]) => {
const newKey = key.split('_')[0].toLowerCase();
if (newKey === id) {
tablesAndValues.push({
table: key,
values: value
});
} else {
getNamesAndValues( value, id, tablesAndValues); }
});
return tablesAndValues;
}

console.log(getNamesAndValues(response.data, 'cstm'));

How to iterate recursively over all children in nested objects

You are passing child which is an object and that is not iterable, you have to pass it's children. You can try checking if child having children array and then iterate children.

function selectActivePage(node) {
for (let child of node) {
child.folded = false;
if(child.children && Array.isArray(child.children) && child.children.length > 0)
selectActivePage(child.children)
}
};

Iterate recursively on properties of an object

Use this instead to replace your emphasized line:

SaveProperties (propertyInfo.GetValue (entity, null));

I would also do something like this to make sure GetValue() is applicable and to avoid multiple calls to it:

object v = propertyInfo.CanRead ?  propertyInfo.GetValue (entity, null) : null;
if (v != null) {
if (...) {
} else {
SaveProperties (v);
}
}


Related Topics



Leave a reply



Submit