2012-02-27 40 views
15

Hãy nói tôi có dữ liệu json nhưLàm thế nào để truy cập vào lồng dữ liệu JSON

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

Bây giờ tôi nhận được trường để được truy cập từ dữ liệu này json như: fields = ["id", "name", "address.streetName"]

Làm thế nào tôi có thể truy cập vào lĩnh vực thứ ba (address.streetName) từ dữ liệu json nhất định theo cách hiệu quả nhất? data.fields[2] không hoạt động

Một khả năng là tôi tạo chuỗi data[address][streetName] bằng cách sử dụng vòng lặp for và thực hiện điều đó nhưng có cách nào hiệu quả không?

+0

Có vấn đề gì với data.address.streetName? – Dampsquid

+0

Tôi nhận được address.streetName như một biến từ một nơi nào đó. Tôi có nghĩa là ai đó đang đi qua tôi x nơi x = "address.streetName" – user999491

+0

Hmm, trong trường hợp đó, bạn sẽ phải sử dụng 'eval', đó không phải là chính xác lý tưởng! Để sử dụng eval: 'var your_variable = eval (" dữ liệu. "+ X);' – JamieJag

Trả lời

29

Thành thật mà nói, tôi không thể hiểu được vấn đề của bạn. JSON đã được cấu trúc, tại sao bạn cần phải thay đổi cấu trúc?

Trong bạn trường hợp, tôi sẽ truy cập vào nó như sau:

data.address.streetName; 

Nếu, bởi bất kỳ cơ hội, những gì bạn muốn là để traverse dữ liệu, bạn sẽ cần:

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

Cập nhật

Sau khi đọc dưới đây, những gì người dùng này cần có vẻ rõ ràng hơn. Cho các tên thuộc tính dưới dạng một chuỗi, anh ta muốn truy cập đối tượng.

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 Tôi nghĩ rằng bạn đã có 'data.address.streetName' đúng, đó là những gì ông đang tìm kiếm có lẽ mặc dù câu hỏi của ông không rõ ràng. – Sarfraz

+0

Hmm Tôi sẽ giải thích nó một lần nữa: address.streetName là một biến đến với tôi. Tôi có dữ liệu ở định dạng json với tôi. Tình huống giống như tôi có dữ liệu ở định dạng JSON và ai đó đang chuyển "address.streetName" cho tôi và vấn đề là làm cách nào tôi nên truy cập giá trị cho khóa này từ dữ liệu – user999491

+0

@ user999491 Xem câu trả lời cập nhật của tôi. – Christian

2

Biến số data của bạn không có thuộc tính fields và đó là lý do tại sao data.fields[2] không hoạt động. Tôi nghĩ rằng những gì bạn đang cố gắng làm ở đó là data[fields[2]], sẽ hoạt động cho một đối tượng đơn giản, nhưng bạn không thể lập chỉ mục vào một đối tượng phức tạp như thế.

+0

có chính xác như vậy là có cách hiệu quả để truy cập dữ liệu lồng nhau so với sau: col = "address.streetName" // key exp = "x" // dữ liệu; col = col.split (".") cho (var i = 0; i user999491

2

bạn có thể truy cập vào nó theo cách này data.address.streetName

+0

Có nhưng tôi nhận được khóa ở định dạng chuỗi ... Tôi có nghĩa là ai đó đang chuyển cho tôi "address.streetName" – user999491

+0

@ user999491 Bạn có thể đã nói như vậy ngay từ đầu ... – Christian

+0

bạn không thể lặp lại thông qua hồ sơ và làm một 'nếu address.streetname == x' –

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

Output:

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

Cảm ơn Michael .. đây là những gì tôi đang làm .. tự hỏi nếu có thể có cách hiệu quả hơn để làm điều đó .. – user999491

+0

Chỉ cần nhận ra tôi đã làm eval không cần thiết sau khi xây dựng dữ liệu ["address"] ["streetName"] sử dụng cho vòng lặp. Tôi nghĩ câu trả lời của bạn là hiệu quả nhất. Cảm ơn rất nhiều. – user999491

6

câu chuyện dài ngắn, bạn có thể sử dụng các ký hiệu mảng object[property] thay vì object.property; đây là đặc biệt hữu ích khi các phím chứa các ký tự đặc biệt:

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 

Bạn có thể sử dụng toán tử typeof để kiểm tra xem một tài sản tồn tại hay không trước khi sử dụng nó:

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

Nếu bạn sử dụng lodash (rất thư viện tiện ích phổ biến), bạn có thể sử dụng _.get().

ví dụ:

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

Nếu liên quan đến mảng, bạn cũng có thể sử dụng đường dẫn chuỗi như 'address[0].streetName'.

ví dụ:

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 

Bên trong, nó sử dụng toPath() chức năng để chuyển đổi chuỗi đường dẫn (ví dụ address.streetName) vào một mảng (ví dụ ['address', 'streetName']), và sau đó sử dụng một chức năng để truy cập dữ liệu tại đường dẫn đưa ra trong vòng các đối tượng.

Các chức năng tiện ích tương tự khác bao gồm _.set()_.has(). Kiểm tra chúng ra.

+0

lodash của nó khá thẳng về phía trước để làm điều này. –

Các vấn đề liên quan