2010-12-03 98 views
4

我從CouchDB數據庫收集了一些不同的,複雜的JSON對象。每個包含嵌套屬性的多層次 - 例如,在javascript中,測試屬性深深嵌套在對象圖中?

tps_report.personnel_info.productivity.units_sold = 8 

我想通過這些對象進行迭代和做的東西與他們:例如,

// writes units sold from each TPS report: 
for (i in tpsReports) { 
    if (tpsReports[i].personnel_info.productivity.units_sold < 10) { 
    fireEmployee(); 
    } 
} 

的問題是,許多TPS報告唐沒有設置所有這些屬性。因此,如果我嘗試這樣做,那麼在第一次循環獲取到沒有「personnel_info」屬性的報告時,會出現錯誤,從而嘗試查找「undefined」的「productivity」屬性。我寧願發生的是,條件只是跳過它並繼續。

我看到周圍這兩種方式,這兩種看似醜陋的我

  1. 測試每個屬性分別與嵌套條件
  2. 封裝在一個try/catch塊行捕獲錯誤和忽視它

我更喜歡的是像PHP的isset()函數,它不會拋出一個錯誤,無論你餵它它 - 它只會告訴你,你是否是特定的變量尋找存在與否。所以,就像

// writes units sold from each TPS report: 
for (i in tpsReports) { 
    if (isset(tpsReports[i].personnel_info.productivity.units_sold)){ 
    if (tpsReports[i].personnel_info.productivity.units_sold < 10) { 
     fireEmployee(); 
    } 
    } 
} 

有什麼想法?

回答

5
function isset(obj, propStr) { 
    var parts = propStr.split("."); 
    var cur = obj; 
    for (var i=0; i<parts.length; i++) { 
     if (!cur[parts[i]]) 
      return false; 
     cur = cur[parts[i]]; 
    } 
    return true; 
} 

請注意,第二個參數是一個字符串,因此在訪問不存在的屬性上的屬性時不會引發異常。

0

我真的很喜歡jsonpath的優雅,相當於xpath,但對於json。

http://goessner.net/articles/JsonPath/

在那裏,你可以做這樣的表達式:

var units_sold = jsonPath(tpsResports, '$.[*].personnel_info.productivity.units_sold'); 
// units_sold is array of found values... 

(我沒有仔細檢查我的表達,也可能是錯誤的,你想在你的例子是什麼)

0

醜陋的方式:

for (i in tpsReports) { 
    try { 
    if(tpsReports[i].personnel_info.productivity.units_sold < 10) { 
     fireEmployee(); 
    } 
    } catch (e) {} 
} 
+0

謝謝,這是我在「2.將該行放在try/catch塊中以捕獲錯誤並忽略它」的方法。 – thisismyname 2010-12-06 05:14:35

2

Theres a function defined on this blog安全地從JS對象讀取嵌套的屬性

它允許你挖掘一個屬性的對象...即。

safeRead(tps_report, 'personnel_info', 'productivity', 'units_sold'); 

如果對象鏈的任何部分爲空或未定義它返回一個空字符串....

2
/** 
* units sold from each TPS report 
*/ 

var units; 

// the hard way 
units = (report && report.personnel && report.personnel.info && 
     report.personnel.info.sales && report.personnel.info.sales.units && 
     report.personnel.info.sales.units.sold) || 0; 

// the easy way 
units = selectn('personnel.info.sales.units.sold', report) || 0; 

// resulting action 
if (units < 10) fireEmployee(); 

無恥插頭:我的selectn作者。它可通過npm install selectnbower install selectncomponent install wilmoore/selectn獲得。

查看自述文件中的示例以瞭解爲什麼這比克隆的isset好。您還可以將它用作謂詞謂詞,以便擦除不包含特定深層嵌套屬性的嵌套對象。

1

您可以使用我的ObjectPath查詢大型嵌套JSON文檔。我構建它的原因是編程語言中沒有好的工具來處理JSON,就像問題中提到的一樣。

該項目是開源和AGPL許可證。

http://adriank.github.io/ObjectPath/

Javascript實現不是最優化的,缺乏的Python的功能一半,但我渴望在需要時由社區增加新的東西 - 只要ping通我有什麼事對你是重要的。