简体   繁体   中英

JSON.parse reviver function nested objects

My goal is to tell the JSON.parse function with the optional reviver argument that I would like it if the string being passed to the calc(string) function has a key named "expr" to perform the operation inside of that expression, and then continue to work outwards to operate on the rest of the string.

Every time I run this I am getting NaN .

If I comment out the two last calc(string) calls before console.log(initNumber) then the program runs as expected.

So if the key is "expr" and the value of the nested "op" key is "add" then perform the add() function on that nested object. Same goes for if the "op" key is "subtract" .

Any help is immensely appreciated.

var initNum = 0;

var calc = function(string) {
    var calcString = JSON.parse(string, reviver);

    add(calcString);
    subtract(calcString);
};

var add = function(string) {
    if (string["op"] == "add") {
    var numString = parseInt(JSON.stringify(string["number"]));
    initNum = numString + initNum;
    return initNum;
  }
}
var subtract = function(string) {
    if (string["op"] == "subtract") {
    var numString = parseInt(JSON.stringify(string["number"]));
    initNum = initNum - numString;
    return initNum;
  }
}

var reviver = function(key, val) {
  if (key == "expr") {
    if (val.op == "add") {
      return add(val);
    }
    else if (val.op == "subtract") {
      return subtract(val);
    }
  }
    else {
      return val;
    }
};

calc('{"op" : "add", "number" : 5}');
calc('{"op" : "subtract", "number" : 2}');
calc('{"op" : "add", "number" : 19}');
calc('{"op": "subtract", "expr" : {"op" : "add", "number" : 15}}');
calc('{"op": "add", "expr" : {"op" : "add", "expr" : {"op" : "subtract", "number" : 3}}}');
console.log(initNum);

A few points :

  • reviver will give you the already parsed values, you don't need to parse them again.
  • if you convert an expr into a value, your add and subtract functions need to be able to read those values, and not just number - I think, maybe you intend for different logic. That's why I get operand the way I do below. Either way, you need to be aware that there might not be a number argument, and handle that.
  • the reason you were getting NaN is because of the above- you were trying to get the number from objects which didn't have one(the results of reviving expr s), which gives you undefined which broke the calculations.

Basically, remember that

{"op": "subtract", "expr" : {"op" : "add", "number" : 15}}

goes to

{"op": "subtract", "expr" : 37}

after you revive the expression, so you need to handle that.

 var initNum = 0; var calc = function(string) { var calcObj = JSON.parse(string, reviver); add(calcObj); subtract(calcObj); }; var add = function(obj) { if (obj["op"] == "add") { var operand = (obj["number"])? obj["number"] : obj["expr"]; initNum = operand + initNum; console.log("running total : "+initNum); return initNum; } } var subtract = function(obj) { if (obj["op"] == "subtract") { var operand = (obj["number"])? obj["number"] : obj["expr"]; initNum = initNum - operand; console.log("running total : "+initNum); return initNum; } } var reviver = function(key, val) { if (key == "expr") { if (val.op == "add") { return add(val); } else if (val.op == "subtract") { return subtract(val); } } else { return val; } }; calc('{"op" : "add", "number" : 5}'); calc('{"op" : "subtract", "number" : 2}'); calc('{"op" : "add", "number" : 19}'); calc('{"op": "subtract", "expr" : {"op" : "add", "number" : 15}}'); calc('{"op": "add", "expr" : {"op" : "add", "expr" : {"op" : "subtract", "number" : 3}}}'); console.log(initNum);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM