How to parse (infinite) nested object notation?

I am currently breaking my head about transforming this object hash:

"food": {
    "healthy": {
        "fruits": ['apples', 'bananas', 'oranges'],
        "vegetables": ['salad', 'onions']
    },
    "unhealthy": {
        "fastFood": ['burgers', 'chicken', 'pizza']
    }
}

to something like this:

food:healthy:fruits:apples
food:healthy:fruits:bananas
food:healthy:fruits:oranges
food:healthy:vegetables:salad
food:healthy:vegetables:onions
food:unhealthy:fastFood:burgers
food:unhealthy:fastFood:chicken
food:unhealthy:fastFood:pizza

In theory it actually is just looping through the object while keeping track of the path and the end result.

Unfortunately I do not know how I could loop down till I have done all nested.

var path;
var pointer;
function loop(obj) {
    for (var propertyName in obj) {
        path = propertyName;
        pointer = obj[propertyName];

        if (pointer typeof === 'object') {
            loop(pointer);
        } else {
            break;
        }        
    }
};

function parse(object) {
    var collection = [];

};

There are two issues which play each out:

  1. If I use recurse programming it looses the state of the properties which are already parsed.
  2. If I do not use it I cannot parse infinite.

Is there some idea how to handle this?

Regards

Answers:

Answer

The reason your recursive function doesn't work is you're storing the state outside it. You want the state inside it, so that each invocation tracks its state.

Something like this:

var obj = /* ... the object ... */;
var lines = loop([], "", obj);

function loop(lines, prefix, obj) {
    var key, sawOne = false;

    // Is it an array?
    if (Object.prototype.toString.call(obj) === "[object Array]") {
        // Yes, in your example these are all just strings to put
        // at the end, so do that
        for (key = 0; key < obj.length; ++key) {
             lines.push(prefix + ":" + obj[key]);
        }
    }
    else {
        // No, it's an object. Recurse for each property, adding the
        // property to the prefix we use on each line
        for (key in obj) {
            loop(lines, prefix ? (prefix + ":" + key) : key, obj[key]);
        }
    }

    return lines;
}

Completely off-the-cuff and untested, but you get the idea.

Edit: But apparently it works, as Michael Jasper was kind enough to make a live demo (source) which I've tweaked slightly.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.