键值对JSON对象解析数组

时间:2017-08-10 13:44:49

标签: javascript json parsing

您好我在文件中有一个给定的JSON对象数组:

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"
      }
   }
]

以下是我阅读的方式。

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;
    }
}

他们是否可以优化它,因为我将在以后递归搜索多个myID。

4 个答案:

答案 0 :(得分:0)

将你的json变成一个对象而不是一个数组。然后你可以快速查找。

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

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

答案 1 :(得分:0)

命名'obj'在这里有点令人困惑,因为它实际上是一个对象数组(来自JSON文件)。

尝试类似:

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 : '';
}

答案 2 :(得分:0)

基于此要求:

  

他们有什么方法可以优化它......

您可能希望将ID值存储为地图的键,以及与其相关的任何信息作为值。这样,无论何时进行搜索,如果您已经拥有ID,则可以在固定时间内访问该ID的数据,或O(1),而不是线性时间,或O(n)。

这是加速搜索的唯一方法,没有更复杂的数据结构,但它有一个警告,即您不再有列表。您将使用地图。

改变这个:

[ 
{
 "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" }
}
]

对此:

{
 "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" 
 }
}

现在你不需要任何循环。你只有一个对象,对象的每个成员代表一个不同的项目。

在您的代码中,您只需执行obj[myId]即可获得undefined,如果它不存在,或者您将获得匹配结果的对象。

搜索可能是最快的,但同样需要类似地图的数据结构,而不是列表。

如果您绝对必须使用列表,那么唯一真正的优化如下:

  • 缓存列表长度,因此您不必在循环的每次迭代中计算它

您的新getInfobyID可能如下所示:

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

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

答案 3 :(得分:0)

您可以使用Array.reducearray转换为keyidvalueinfo的对象。

现在您只需返回object[id]并获取info,而无需每次都进行迭代。

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"));