简体   繁体   English

如何访问嵌套的 JSON 数据

[英]How to access nested JSON data

Let say I have json data like假设我有 json 数据,例如

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

Now I am getting fields to be accessed from this json data like: fields = ["id", "name", "address.streetName"]现在我正在从这个 json 数据中访问字段,例如: fields = ["id", "name", "address.streetName"]

How could I access third field ( address.streetName ) from given json data in most efficient way?如何以最有效的方式从给定的 json 数据访问第三个字段( address.streetName )? data.fields[2] doesn't work data.fields[2]不起作用

One possibility is I construct data[address][streetName] string using a for loop and do eval of that but is there any efficient way of doing this?一种可能性是我使用 for 循环构造data[address][streetName]字符串并对其进行评估,但是有没有有效的方法来做到这一点?

To be honest, I can't understand your problem.老实说,我无法理解你的问题。 JSON is already structured out, why do you need to change the structure? JSON 已经结构化了,为什么还要改结构呢?

In you case, I would access it as follows:在你的情况下,我会按如下方式访问它:

data.address.streetName;

If, by any chance, what you want is to traverse the data, you would need:如果有任何机会,您想要遍历数据,则需要:

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

Update更新

After reading below, what this user needs seems more obvious.阅读下文后,该用户的需求似乎更加明显。 Given property names as a string, s/he wants to access the object.给定属性名称作为字符串,他/她想要访问该对象。

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

If you use lodash (a very popular utility library), you can use _.get() .如果您使用lodash (一个非常流行的实用程序库),您可以使用_.get()

eg例如

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

If it involves an array, you can use string path like 'address[0].streetName' as well.如果它涉及一个数组,你也可以使用像'address[0].streetName'这样'address[0].streetName'字符串路径。

eg例如

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

Internally, it uses toPath() function to convert string path (eg address.streetName ) into an array (eg ['address', 'streetName'] ), and then uses a function to access the data at the given path within the object.在内部,它使用toPath()函数将字符串路径(例如address.streetName )转换为数组(例如['address', 'streetName'] ),然后使用函数访问对象内给定路径处的数据.

Other similar utility functions include _.set() and _.has() .其他类似的实用函数包括_.set()_.has() Check them out.去看一下。

Long story short, you can use the array notation object[property] instead of object.property ;长话短说,您可以使用数组符号object[property]而不是object.property this is specially useful when the keys contains special characters:当键包含特殊字符时,这特别有用:

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

You can use the typeof operator to check whether a property exists or not before using it:您可以使用typeof运算符在使用之前检查属性是否存在:

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

Your data variable doesn't have a fields property, and that's why data.fields[2] doesn't work.您的data变量没有fields属性,这就是data.fields[2]不起作用的原因。 I think what you're trying to do there is data[fields[2]] , which would work for a simple object, but you can't index into a complex object like that.我认为你正在尝试做的是data[fields[2]] ,它适用于一个简单的对象,但你不能像那样索引到一个复杂的对象。

您可以通过这种方式访问​​它data.address.streetName

JavaScript: 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

This is a function I use to find data in nested objects:这是我用来在嵌套对象中查找数据的函数:

Object.prototype.find = function() {
  try {
    return Array.prototype.slice.call(arguments).reduce(function(acc, key) {
      return acc[key]
    }, this)
  }
  catch(e) {
    return 
  }
}

Data structure:数据结构:

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

Function call:函数调用:

data.find("address","streetName")

Returns:返回:

"cde"

I did it like this:我是这样做的:

var data = {
    "id": 1,
    "name": "abc",
    "addresses": [{
        "streetName": "cde",
        "streetId": 2
    }, {
        "streetName": "xyz",
        "streetId": 102
    }, ]
}

data2 = data["addresses"]
for (let i in data2) {
    console.log(data2[i]["streetName"]);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM