2012-02-27 182 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