Haring10 February 2016

Recursive JS function misses every second loop

I have a function to take a format of

u1fsQExd1aZmnpL : {
    2FNdVdkaefaD6xQ : {
        fZ0zn6d51TgVqID : {
            05E1JSFYVHJlGVP : {}
        }
    }
}

And change it to

u1fsQExd1aZmnpL : {
    subfields : {
        2FNdVdkaefaD6xQ : {
            subfields : {
                fZ0zn6d51TgVqID : {
                    subfields : {
                        05E1JSFYVHJlGVP : {
                            subfields : {}
                        }
                    }
                }
            }
        }
    }
}

However, it comes out as:

u1fsQExd1aZmnpL : {
    subfields : {
        2FNdVdkaefaD6xQ : {
            fZ0zn6d51TgVqID : {
                subfields : {
                    05E1JSFYVHJlGVP : {}
                }
            }   
        }
    }
}

Note: it misses the second 'subfields' step.

It does this every second loop. ie: The next ID that is added to 05E1JSFYVHJlGVP will be inside of it, without a subfields parent, but it will have a subfields child inside of it.

My method is:

        function get_into_subfields(form_structure) {
            for(var mainid in form_structure) {
                if(!form_structure[mainid].hasOwnProperty('subfields')) {
                    form_structure[mainid]['subfields'] = {};
                }
                for(var key in form_structure[mainid]) {
                    if(key != 'subfields') {
                        form_structure[mainid]['subfields'][key] = get_into_subfields(form_structure[mainid][key]);
                        delete(form_structure[mainid][key]);
                    }
                }
            }
            return form_structure;
        }

Any ideas as to what I am doing wrong?

EDIT:

Here is the

Answers


somethinghere February 2016

This is pretty simplify able, but I think your function is slightly complicated. The problem is that you do not want the first one to be a subfields object, but why not? That will make it easier and you will get the same result by simply adding .subviews to your result.

var obj = {'u1fsQExd1aZmnpL' : {'2FNdVdkaefaD6xQ' : {'fZ0zn6d51TgVqID' : { '05E1JSFYVHJlGVP' : {}}}}}

function subfields(data){
  // Simply create a standard object that you can return
  var result = {subfields:{}};
  for(var key in data){
    // now recursively add it
    result.subfields[key] = subfields(data[key])
  }
  return result;
}

console.log('The full result', subfields(obj));
console.log('Ignore the initial subfield returned', subfields(obj).subfields);
document.write('<pre>' + JSON.stringify(subfields(obj).subfields) + '</pre>')

This will leave you with an empty object at the end of the chain, which is assume is not a problem, although there is still a lot you can do to make sure this won't error out, the basics work.


Nina Scholz February 2016

Just get all keys and iterateover the properties. If the item is an object, iterate over the item.

function go(r, o) {
    Object.keys(o).forEach(function (k) {
        r[k] = { subfields: {} };
        typeof o[k] === 'object' && go(r[k].subfields, o[k]);
    });
}

var source = { 'u1fsQExd1aZmnpL': { '2FNdVdkaefaD6xQ': { 'fZ0zn6d51TgVqID': { '05E1JSFYVHJlGVP': {} } } } },
    target = {};

go(target, source);
document.write('<pre>' + JSON.stringify(target, 0, 4) + '</pre>');

Post Status

Asked in February 2016
Viewed 2,070 times
Voted 11
Answered 2 times

Search




Leave an answer