Jezcentral
Jezcentral

Reputation: 422

Iterating through nested objects/arrays

I'm trying to iterate through an object that can have several levels of arrays.

Eg.

I start with:

var htmlString = {
    "div": [{
        "attributes": {
            "class": "myDivClass"
        },
        "p": [{
            "attributes": {
                "class": "myPClass"
            }
        }]
    }]
};

Now let's add something else:

var htmlString = {
    "div": [{
        "attributes": {
            "class": "myDivClass"
        },
        "p": [{
            "attributes": {
                "class": "myPClass"
            },
            "span": [{
                "attributes": {
                    "class": "mySpanClass"
                }
            }]
        }]
    }]
};

The code I'm working on will have the same sort of shape as:

var childNode = document.createElement("myChildElement");
for (key in value) {
    if (value.hasOwnProperty(key)) {
        if (key == "attributes") {
            childNode.setAttributes(myAttributes); // loop through attributes on the element
        }
        else {
            //the same code ad infinitum
            var childChildNode = document.createElement("myChildChildElement");
            // etc etc....
        }
    }
}
parentNode.appendChild(childNode);

The rules of each extra element are the same, so I should be able to just loop down this data structure the same way for both pieces of code, I'm just not sure how, although I'll bet there is a while() loop in there somewhere. Can anyone tell me?

P.S. Native javascript, please, no jQuery! (Although, if you have YUI3 answer I'd be very interested).

Upvotes: 1

Views: 1815

Answers (2)

Qnan
Qnan

Reputation: 3744

var createTree = function (node, data) {
    for (var key in data) {
        if (data.hasOwnProperty(key)) {
            if (key == "attributes") {
                node.setAttributes(myAttributes); // loop through attributes on the element
            }
            else {
                for (var i = 0; i < data[key].length; ++i) {
                    var childNode = document.createElement(key);
                    createTree(childNode, data[key][i]);
                    node.appendChild(childNode);
                }
            }
        }
    }
}

createTree(parentNode, htmlString);

Upvotes: 2

Jezcentral
Jezcentral

Reputation: 422

Okay, Qnan's code needed a little tweak, as it wasn't dealing with getting to the end of a end of a branch properly. Once it got to the end, there was nothing to check, and the null length of nothing was causing an error.

I know it is bad practice, but it's late, and I need this fixed, so here is my tweak.

var createTree = function (node, data) {
    for (key in data) {
        if (data.hasOwnProperty(key)) {
            if (key == "attributes") {
                node.setAttributes(myAttributes); // loop through attributes on the element
            }
            else {
                try {
                    for (var i = 0; i < data[key].length; ++i) {
                        var childNode = document.createElement(key);
                        createTree(childNode, data[key][i]);
                        node.appendChild(childNode);
                    }
                }
                catch(error) {
                    console.log("there was an error");
                }
            }
        }
    }
}

createTree(parentNode, htmlString);

Yes, that's right, I bury the error by try/catching it...and then doing nothing. Don't try this at home kids!

Qnan, many thanks again.

Upvotes: 0

Related Questions