mwilson
mwilson

Reputation: 12900

Recursive Function not working correctly

I have a recusive function that is supposed to loop through a json object and output the expression. However, my recusion seems to be off because it's outputting field1 != '' AND field3 == '' when it should be outputting field1 != '' AND field2 == '' AND field3 == ''

I've tried a couple different things and the only way I can get it to work is by creating a global variable outstring instead of passing it to the function. Where am I off? When I step through it, i see a correct result but once the stack reverses, it start resetting outstring and then stack it back up again but leaves out the middle (field2).

JSFiddle

function buildString(json, outstring) {
        var andor = json.condition;
    for (var rule in json.rules) {
        if (json.rules[rule].hasOwnProperty("condition")) {
            buildString(json.rules[rule], outstring);
        } else {
            var field = json.rules[rule].id;
            var operator = json.rules[rule].operator;
            var value = json.rules[rule].value == null ? '' : json.rules[rule].value;
            outstring += field + ' ' + operator + ' ' + value;
            if (rule < json.rules.length - 1) {
                outstring += ' ' + andor + ' ';
            }
        }
    }
    return outstring;
}

var jsonObj = {"condition":"AND","rules":[{"id":"field1","operator":"!= ''","value":null},{"condition":"AND","rules":[{"id":"field2","operator":"== ''","value":null}]},{"id":"field3","operator":"== ''","value":null}]};

$('#mydiv').text(buildString(jsonObj, ""));

Upvotes: 2

Views: 566

Answers (2)

charlietfl
charlietfl

Reputation: 171679

The function has a return of a string.

When you call the function recursively from within itself, you aren't doing anything with the returned string from that instance, just calling the function which has nowhere to return to

Change:

    if (json.rules[rule].hasOwnProperty("condition")) {
       buildString(json.rules[rule], outstring);
    } 

To

    if (json.rules[rule].hasOwnProperty("condition")) {
       // include the returned value in concatenated string
       outstring += buildString(json.rules[rule], outstring);
    }

DEMO

Upvotes: 1

Thomas
Thomas

Reputation: 3593

Why so complicated?

function buildString(obj) {
    return "condition" in obj?
        obj.rules.map(buildString).join(" " + obj.condition + " "):
        obj.id + " " + obj.operator + " " + string(obj.value);
}

//this problem occurs quite often, write a utility-function.
function string(v){ return v == null? "": String(v) }

Upvotes: 0

Related Questions