2012-02-27 181 views
15

讓說我有一個像如何訪問嵌套的JSON數據

data = {"id":1, 
     "name":"abc", 
     "address": {"streetName":"cde", 
        "streetId":2 
        } 
     } 

現在我越來越場從這樣的JSON數據訪問的JSON數據:fields = ["id", "name", "address.streetName"]

我怎麼能進入第三場(address.streetName )從最有效的方式給定json數據? data.fields[2]不起作用

一種可能性是我構造data[address][streetName]字符串使用for循環,並做了評估,但有沒有這樣做的有效方式?

+0

data.address.streetName有什麼問題? – Dampsquid 2012-02-27 10:14:15

+0

我從某處獲取address.streetName作爲變量。我的意思是有人通過我x其中x =「address.streetName」 – user999491 2012-02-27 10:32:02

+0

嗯,在這種情況下,你必須使用'eval',這不完全理想! 使用eval: '變種your_variable = EVAL;' – JamieJag 2012-02-27 11:19:16

回答

29

說實話,我不明白你的問題。 JSON已經構建出來了,爲什麼你需要改變結構?

在你的情況,我可以按如下方式訪問:

data.address.streetName; 

如果任何機會,你想要的是遍歷的數據,你將需要:

function traverse_it(obj){ 
    for(var prop in obj){ 
     if(typeof obj[prop]=='object'){ 
      // object 
      traverse_it(obj[prop[i]]); 
     }else{ 
      // something else 
      alert('The value of '+prop+' is '+obj[prop]+'.'); 
     } 
    } 
} 

traverse_it(data); 

更新

閱讀以下內容後,此用戶需要的內容似乎更加明顯。給定屬性名稱爲一個字符串,他/她想訪問該對象。

function findProp(obj, prop, defval){ 
    if (typeof defval == 'undefined') defval = null; 
    prop = prop.split('.'); 
    for (var i = 0; i < prop.length; i++) { 
     if(typeof obj[prop[i]] == 'undefined') 
      return defval; 
     obj = obj[prop[i]]; 
    } 
    return obj; 
} 

var data = {"id":1,"name":"abc","address":{"streetName":"cde","streetId":2}}; 
var props = 'address.streetName'; 
alert('The value of ' + props + ' is ' + findProp(data, props)); 
+0

+1我認爲你有'data.address.streetName'的權利,這是他正在尋找的可能,但他的問題不明確。 – Sarfraz 2012-02-27 10:27:11

+0

嗯,我會再解釋一次:address.streetName是一個變量來找我。我有json格式的數據。這種情況就像我有JSON格式的數據,並且有人向我傳遞「address.streetName」,問題是我該如何從數據訪問此密鑰的值 – user999491 2012-02-27 10:28:33

+0

@ user999491請參閱我的更新回答。 – Christian 2012-02-27 10:36:57

2

您的data變量沒有fields屬性,這就是爲什麼data.fields[2]不起作用。我認爲你在那裏試圖做的是data[fields[2]],它可以用於一個簡單的對象,但是你不能像這樣索引到一個複雜的對象。

+0

是正確所以有訪問嵌套的數據比較,以下述的任何有效的方式(+ X 「數據」。):山口= 「address.streetName」 //鍵 exp =「x」// data;對於(var i = 0; i user999491 2012-02-27 10:21:36

2

您可以訪問它這樣data.address.streetName

+0

是的,但我得到的字符串格式的關鍵...我的意思是有人通過我「address.streetName」 – user999491 2012-02-27 10:27:07

+0

@ user999491你可以這樣說,在第一位... – Christian 2012-02-27 10:31:25

+0

你不能只是通過你的循環記錄並做一個'如果address.streetname == x' – 2012-02-27 10:35:44

1

的JavaScript:

function getProperty(json, path) { 
    var tokens = path.split("."); 
    var obj = json; 
    for (var i = 0; i < tokens.length; i++) { 
     obj = obj[tokens[i]]; 
    } 
    return obj; 
} 

var data = { 
    id: 1, 
    name: "abc", 
    address: { 
     streetName: "cde", 
     streetId: 2 
    } 
}; 

var fields = ["id", "name", "address.streetName"]; 

for (var i = 0; i < fields.length; i++) { 
    var value = getProperty(data, fields[i]); 
    console.log(fields[i] + "=" + value); 
} 

輸出:

id=1 
name=abc 
address.streetName=cde 
+0

謝謝邁克爾..這是我正在做..只是想知道是否可以有更有效的方式做到這一點.. – user999491 2012-02-27 10:35:33

+0

剛剛意識到我做了不必要的評估後,構建數據[「地址」] [「streetName」]使用for循環。我認爲你的答案是最有效的。非常感謝。 – user999491 2012-02-27 10:45:34

6

長話短說,你可以使用數組符號object[property]而不是object.property;這是特別有用的,當按鍵包含特殊字符:

var data = { 
    "id": 1, 
    "name": "abc", 
    "address": { 
     "streetName": "cde", 
     "streetId": 2 
    } 
} 

data.address.streetName;    // (1) dot notation 
data["address"]["streetName"];  // (2) array notation 
var field = "streetName"; 
data["address"][field];    // (3) variable inside array notation 
var fields = "address.streetName".split("."); 
data[fields[0]][fields[1]];   // (4) specific to your question 

可以使用typeof運營商檢查屬性是否存在使用前:

typeof data["address"]["streetName"]; // returns "string" 
typeof data["address"]["foobarblah"]; // returns "undefined" 
12

如果使用lodash(一個非常流行的實用程序庫),您可以使用_.get()

例如

var data = { 
    "id":1, 
    "name": "abc", 
    "address": { 
    "streetName": "cde", 
    "streetId":2 
    } 
} 
_.get(data, 'address.streetName'); 
// 'cde' 
_.get(data, ['address', 'streetName']); 
// 'cde' 

如果涉及一個數組,你可以使用字符串路徑像'address[0].streetName'爲好。

例如

var data = { 
    "id":1, 
    "name": "abc", 
    "addresses": [ 
    { 
     "streetName": "cde", 
     "streetId": 2 
    }, 
    { 
     "streetName": "xyz", 
     "streetId": 102 
    }, 
    ] 
} 
_.get(data, 'addresses[0].streetName'); 
// cde 
_.get(data, [address, 1, streetName]); 
// xyz 

在內部,它使用toPath()函數字符串路徑(例如address.streetName)轉換成陣列(例如['address', 'streetName']),然後使用一個函數在對象內給定的路徑來訪問數據。

其他類似的實用功能包括_.set()_.has()。去看一下。

+0

lodash它非常簡單直接做到這一點。 – 2017-08-12 18:10:38