2013-04-13 21 views
1

我正在使用一個JSON對象,它可以在任何葉上有屬性ids。我想遍歷該對象並查找ids屬性的所有實例,並將每個ID存儲在集合中。如何遍歷JSON對象查找特定屬性並將其內容推送到數組?

嘲笑JSON對象(ids屬性可能在更深的屬性位置)。

{ 
    "id": "b38a683d-3fb6-408f-9ef6-f4b853ed1193", 
    "foo": { 
    "ids": [ 
     { 
     "id": "bd0bf3bd-d6b9-4706-bfcb-9c867e47b881" 
     }, 
     { 
     "id": "d1cc529d-d5d2-4460-b2bb-acf24a7c5999" 
     }, 
     { 
     "id": "b68d0c8c-548e-472f-9b01-f25d4b199a71" 
     } 
    ], 
    "baz": "super" 
    }, 
    "bar": { 
    "ids": [ 
     { 
     "id": "bd0bf3bd-d6b9-4706-bfcb-9c867e47b881" 
     }, 
     { 
     "id": "d1cc529d-d5d2-4460-b2bb-acf24a7c5999" 
     }, 
     { 
     "id": "b68d0c8c-548e-472f-9b01-f25d4b199a71" 
     } 
    ] 
    } 
} 

我使用以下代碼來遍歷上述JSON。

var jsonFile = require('./file_test.json'); // the above in my local directory 

function traverse(obj, ids) { 
    for (var prop in obj) { 
    if (typeof obj[prop] == "object" && obj[prop]) { 
     if (prop == 'ids') { 
     for (var i = obj[prop].length - 1; i >= 0; i--) { 
      ids.push(obj[prop][i]._id); 
     }; 
     } 
     traverse(obj[prop], ids); 
    } 
    } 
} 

var ids = new Array(); 
traverse(jsonFile, ids); 

console.log('ids', ids); 

以上的網下:

ids 
[ 
    'b68d0c8c-548e-472f-9b01-f25d4b199a71', 
    'd1cc529d-d5d2-4460-b2bb-acf24a7c5999', 
    'bd0bf3bd-d6b9-4706-bfcb-9c867e47b881', 
    'b68d0c8c-548e-472f-9b01-f25d4b199a71', 
    'd1cc529d-d5d2-4460-b2bb-acf24a7c5999', 
    'bd0bf3bd-d6b9-4706-bfcb-9c867e47b881' 
] 

雖然我的代碼工作,我不認爲我這樣做的最有效或最佳方式。有沒有更好的方法來查找ids屬性的所有實例?也許沒有傳入一個數組,但返回一個?或者使用ids陣列設置回撥?

回答

2

你有什麼是好的,但是這是一個有點短,使用.MAP功能:

var jsonFile = require('./file_test.json'); // the above in my local directory 
function traverse(obj) { 
    var ids = []; 
    for (var prop in obj) { 
     if (typeof obj[prop] == "object" && obj[prop]) { 
      if (prop == 'ids') { 
       ids = obj[prop].map(function(elem){ 
        return elem.id; 
       }) 
      } 
      ids =ids.concat(traverse(obj[prop])); 
     } 
    } 
    return ids; 
} 

var ids =traverse(jsonFile); 

console.log('ids', ids); 
+0

它聽起來像ids可以嵌套在id上,所以我在if後面遍歷遍歷。 – phillro

0

你基本上試圖做的是對這個JSON對象進行樹搜索,對嗎?所以如果我們假設ids總是一片葉子,那麼我們不需要traverse那些節點,因爲我們知道它們在葉子上,並且將包含我們想要的。

  • 更改if {...} traverseif {...} else {traverse}

如果有可能的ids數據結構更改爲字符串而非對象的列表清單,那麼你將能夠保存迭代在數組上並將它合併到傳入的ids數組中,但它完全取決於上下文以及是否可以進行此更改!

對不起,我沒有更多的幫助!

+0

基本上是樹搜索JSON對象的。不幸的是,不能將id更改爲字符串列表。 – ahsteele

3

如果數據實際上是一個JSON字符串,而不是一個JavaScript對象,你可以有像:

// assuming `json` is the data string 
var ids = []; 
var data = JSON.parse(json, function(key, value) { 
    if (key === "id") 
     ids.push(value); 

    return value; 
}); 

reviverJSON.parse方法。

0

假設ES5可用天然或經由shim

function gimmeIds(obj) { 
    return Object.keys(obj||{}) 
     .reduce(function(ids, key) { 
      if(key === 'ids') { 
       return ids.concat(obj[key].map(function(idObj) { 
        return idObj.id; 
       })); 
      } 

      if(obj[key] && typeof obj[key] == 'object') { 
       return ids.concat(gimmeIds(obj[key])); 
      } 

      return ids; 
     }, []); 
} 
相關問題