2017-08-10 76 views
0

您好我有有JSON對象的給定陣列中的一個文件:陣列鍵值對的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。

回答

0

把你的json變成一個對象而不是數組。然後你可以快速查找。

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

let value = hash["xccdf_saphana.content_profile_test2"].info; 
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 : ''; 
} 
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; 
    } 
} 
0

您可以使用Array.reducearray轉換爲keyidvalue作爲info的對象。

現在您只需返回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"));