简体   繁体   中英

Array of key-value pair JSON object parsing

Hi I have have a given array of JSON object in a file:

file.json:

[ 
   {
      "id": "xccdf_saphana.content_profile_test1",
      "info": {
         "applicable_platforms": ["SUSE", "RHEL", "SUSE FOR SAP APP"],
         "applicable_workloads": "SalesPromo",
         "applicable_compliance": "CIS",
         "type":"System" 
      }
   },
   {
      "id": "xccdf_saphana.content_profile_test2",
      "info": {
         "applicable_workloads": "SalesPromo",
         "applicable_compliance": "CIS",
         "type":"System"
      }
   }
]

Below is the way I am reading it.

var obj = JSON.parse(fs.readFileSync(file.json, 'utf8')); // read the file
myID = "xccdf_saphana.content_profile_test2";

var myInfo = getInfobyID(myID);

function getInfobyID(myID) {
    // Got messed up, tried changing JSON structure multiple time, so that I can easily parse it.
    for(var i=0; i < obj.length; ++i) {
       if(obj[i].id == myID)
          return obj[i].info;
    }
}

Is their any way I can optimize it, as I will be recursively searching for multiple myID later.

Turn your json into an object rather than an array. Then you can make quick lookups.

let hash = obj.reduce((agg, e) => {
  agg[e.id] = e;
  return agg;
}, {});

let value = hash["xccdf_saphana.content_profile_test2"].info;

The naming 'obj' is a bit confusing here since it is actually an array of objects (from the JSON file).

Try something like:

var myArrOfObj = JSON.parse(fs.readFileSync(file.json, 'utf8'));
var myID = "xccdf_saphana.content_profile_test2";

var myInfo = getInfobyID(myID);

function getInfobyID(myID){
   var matchingObj = myArrOfObj.find((obj) => obj.id === myID);

   // Fallback to empty string since there might be no match.
   return (matchingObj) ? matchingObj.info : '';
}

Based on this requirement:

Is their any way I can optimize it...

You may want to store the ID value as the key of a map, and any info related to it as the value. This way, whenever you are searching, if you already have the ID yo can access the data for that ID in constant time, or O(1), as opposed to linear time, or O(n).

This is the only way to speed up your search without more complex data structures, but it comes with one caveat which is that you no longer have a list. You will be using a map.

Change this:

[ 
{
 "id": "xccdf_saphana.content_profile_test1",
 "info": {
      "applicable_platforms": ["SUSE","RHEL","SUSE FOR SAP APP"],
      "applicable_workloads": "SalesPromo",
      "applicable_compliance": "CIS",
      "type":"System" }
},
{
 "id": "xccdf_saphana.content_profile_test2",
 "info": {
      "applicable_workloads": "SalesPromo",
      "applicable_compliance": "CIS",
      "type":"System" }
}
]

To this:

{
 "xccdf_saphana.content_profile_test1": {
      "applicable_platforms": ["SUSE","RHEL","SUSE FOR SAP APP"],
      "applicable_workloads": "SalesPromo",
      "applicable_compliance": "CIS",
      "type":"System" 
 },
 "xccdf_saphana.content_profile_test2": {
      "applicable_workloads": "SalesPromo",
      "applicable_compliance": "CIS",
      "type":"System" 
 }
}

Now you don't need any loops. You just have one object, with each member of the object representing a different item.

In your code, you can simply do obj[myId] and you will either get undefined if it doesn't exist, or you will get an object of the matching result.

This is the fastest a search could possibly be, but again it requires a map-like data structure and not a list.


If you absolutely must use a list, the only real optimization to be made is as follows:

  • Cache your list length, so you do not have to calculate it on each iteration of the loop

Your new getInfobyID could look like this:

function getInfobyID(myID){
    var len = obj.length;

    for (var i=0; i < len; ++i){
        if( obj[i].id == myID)
            return obj[i].info;
    }
}

You can use Array.reduce to convert your array into an object with key as id and value as info .

Now you can just return the object[id] and get the info without iterating everytime.

 var json = [{ "id": "xccdf_saphana.content_profile_test1", "info": { "applicable_platforms": ["SUSE", "RHEL", "SUSE FOR SAP APP"], "applicable_workloads": "SalesPromo", "applicable_compliance": "CIS", "type": "System" } }, { "id": "xccdf_saphana.content_profile_test2", "info": { "applicable_workloads": "SalesPromo", "applicable_compliance": "CIS", "type": "System" } } ]; var data = json.reduce((acc, curr) => { acc[curr.id] = curr.info; return acc; }, {}); function getInfobyID(data, id) { return data[id]; } console.log(getInfobyID(data, "xccdf_saphana.content_profile_test2")); 

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