简体   繁体   中英

refine node.js code to loop through json nested objects

I have the below code that is working, but it seems overweight for purpose. Is there a shorter way to achieve the goal of looping through nested json?

I am running this on lambda and loading the json from s3

myFile.json

 {
  "jsonIsOk": 
    [
     {
       "txt_in": "aaa",
       "txt_out": "111"
     },
     {
       "txt_in": "bbb",
       "txt_out": "222"
     },
     {
      "txt_in": "ccc",
       "txt_out": "333"
     }
    ]
   }

lambda node.js

var isJsnOk = "jsonIsOk";

var s3 = new AWS.S3({httpOptions: { timeout: 2000 }});
var params = {
    Bucket: 'myBucket',
    Key: 'myFile.json',
};

s3.getObject(params, function (err, data) {
    if (err) {
        console.log(err, err.stack);
    } else {
        var loadJson = data.Body.toString();
        var jsnAry = JSON.parse(loadJson);
        if (jsnAry.hasOwnProperty(isJsnOk)) {
            for (var key_01 in jsnAry) {
              if (jsnAry.hasOwnProperty(key_01)) {
                    for (var key_02 in jsnAry[key_01]) {
                        console.log('key_02=' + key_02);
                        if (jsnAry[key_01].hasOwnProperty(key_02)) {
                            for (var key_03 in jsnAry[key_01][key_02]) {
                                console.log('key_03=' + key_03 + ': val_03 =' + jsnAry[key_01][key_02][key_03]);
                            }
                        }
                        console.log("-------");
                    }
                }
            }
        } else {
            console.log("error: json is not ok!");
        }
    }
}

output

key_02=0
key_03=txt_in: val_03 =aaa
key_03=txt_out: val_03 =111
-------
key_02=1
key_03=txt_in: val_03 =bbb
key_03=txt_out: val_03 =222
-------
key_02=2
key_03=txt_in: val_03 =ccc
key_03=txt_out: val_03 =333
-------

There a few prototypes on array which you could use to write that nested loop in a functional way and reduce the your total lines of code (also easier to read imo). This isn't going to produce the output in your example verbatim as I'm not really sure what the meaning of the key value is (there are no keys, it's an array, it has indexes) but hopefully it gives you some ideas of how you could better write the code that is iterating over it

 {
  "jsonIsOk": 
    [
     {
       "txt_in": "aaa",
       "txt_out": "111"
     },
     {
       "txt_in": "bbb",
       "txt_out": "222"
     },
     {
      "txt_in": "ccc",
       "txt_out": "333"
     }
    ]
   }

obj.jsonIsOk.forEach(a => console.log("txt_in: " + a.txt_in + " txt_out: " + a.txt_out));

// prints
txt_in: aaa txt_out: 111
txt_in: bbb txt_out: 222
txt_in: ccc txt_out: 333

You may also find the map prototype useful, it works similarly to this except it returns a new collection which contains the results returned from the function you pass to it (i'm using lambda syntax here, you could just use vanilla js to pass an anonymous function).

You basically loop three times with the same code, which can be made easily recursively:

function iterate(obj,i=1){
  Object.keys(obj).forEach(function(key){
   console.log(" ".repeat(i-1)+"key_0"+i+"="+key);
   if(typeof obj[key] === "object"){
      iterate(obj[key],i+1);
   }else{
      console.log(" ".repeat(i-1)+"value0"+i+"="+obj[key]);
   }
 });
}

And then start like this:

 iterate(obj.jsonIsOk);

http://jsbin.com/zedoluwega/edit?console

Ive also added some spaces to make the structure more clear...

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