我有一个包含对象和数组的嵌套数据结构。我如何提取信息,即访问一个特定的或多个值(或键)?

例如:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

我如何访问项目中的第二个项目的名称?


当前回答

有时,使用字符串访问嵌套对象是可取的。例如,最简单的方法是第一级

var obj = { hello: "world" };
var key = "hello";
alert(obj[key]);//world

但复杂的json通常不是这样。随着json变得越来越复杂,在json中查找值的方法也变得越来越复杂。导航json的递归方法是最好的,如何利用递归取决于要搜索的数据类型。如果涉及到条件语句,json搜索可能是一个很好的工具。

如果已经知道要访问的属性,但是路径很复杂,例如在这个对象中

var obj = {
 arr: [
    { id: 1, name: "larry" },    
    { id: 2, name: "curly" },
    { id: 3, name: "moe" }
 ]
};

你知道你想要得到对象中数组的第一个结果,也许你想使用

var moe = obj["arr[0].name"];

然而,这将导致一个异常,因为对象没有该名称的属性。能够使用这种方法的解决方案是将对象的树形面平直。这可以递归完成。

function flatten(obj){
 var root = {};
 (function tree(obj, index){
   var suffix = toString.call(obj) == "[object Array]" ? "]" : "";
   for(var key in obj){
    if(!obj.hasOwnProperty(key))continue;
    root[index+key+suffix] = obj[key];
    if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"[");
    if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+".");   
   }
 })(obj,"");
 return root;
}

现在,这个复杂的物体可以被平面化

var obj = previous definition;
var flat = flatten(obj);
var moe = flat["arr[0].name"];//moe

下面是使用这种方法的jsFiddle演示。

其他回答

您可以通过这种方式访问它

data.items[1].name

or

data["items"][1]["name"]

两边相等。

我就是这么做的。

 let groups = [
        {
            id:1,
            title:"Group 1",
            members:[
                {
                    id:1,
                    name:"Aftab",
                    battry:'10%'
                },
                {
                    id:2,
                    name:"Jamal",
                },
                {
                    id:3,
                    name:"Hamid",
                },
                {
                    id:4,
                    name:"Aqeel",
                },
            ]
        },
        {
            id:2,
            title:"Group 2",
            members:[
                {
                    id:1,
                    name:"Aftab",
                    battry:'10%'
                },
                {
                    id:2,
                    name:"Jamal",
                    battry:'10%'
                },
                {
                    id:3,
                    name:"Hamid",
                },
               
            ]
        },
        {
            id:3,
            title:"Group 3",
            members:[
                {
                    id:1,
                    name:"Aftab",
                    battry:'10%'
                },
                
                {
                    id:3,
                    name:"Hamid",
                },
                {
                    id:4,
                    name:"Aqeel",
                },
            ]
        }
    ]
    
    groups.map((item) => {
      //  if(item.id == 2){
        item.members.map((element) => {
             if(element.id == 1){
                 element.battry="20%"
             }
         })
        //}
    })
    
    groups.forEach((item) => {
        item.members.forEach((item) => {
            console.log(item)
    })
    })
var ourStorage = {


"desk":    {
    "drawer": "stapler"
  },
"cabinet": {
    "top drawer": { 
      "folder1": "a file",
      "folder2": "secrets"
    },
    "bottom drawer": "soda"
  }
};
ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

or

//parent.subParent.subsubParent["almost there"]["final property"]

基本上,在它下面展开的每个后代之间使用一个点,当你有由两个字符串组成的对象名称时,你必须使用["obj Name"]符号。否则,只要一个点就足够了;

来源:https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-objects

在此基础上,访问嵌套数组将如下所示:

var ourPets = [
  {
    animalType: "cat",
    names: [
      "Meowzer",
      "Fluffy",
      "Kit-Cat"
    ]
  },
  {
    animalType: "dog",
    names: [
      "Spot",
      "Bowser",
      "Frankie"
    ]
  }
];
ourPets[0].names[1]; // Outputs "Fluffy"
ourPets[1].names[0]; // Outputs "Spot"

来源:https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-arrays/

另一份描述上述情况的更有用的文件: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#Bracket_notation

通过点走访问属性:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Dot_notation

这里有4种不同的方法来获得javascript的object属性:

Var数据= { 42岁的代码: 项目:[{ id: 1、 名称:“foo” }, { id: 2 名称:“酒吧” }) }; //方法1 让method1 = data.items[1].name; console.log (method1); //方法二 Let method2 = data.items[1]["name"]; console.log (method2); //方法3 Let method3 = data["items"][1]["name"]; console.log (method3); //方法四解构 让{items: [, {name: second_name}]} =数据; console.log (second_name);

以防万一,有人在2017年或以后访问这个问题,并寻找一种容易记住的方法,这里有一篇关于在JavaScript中访问嵌套对象而不被迷惑的详细博客文章

无法读取未定义错误的属性“foo”

1. Oliver Steele的嵌套对象访问模式

最简单、最干净的方法是使用Oliver Steele的嵌套对象访问模式

const name = ((user || {}).personalInfo || {}).name;

用这个符号,你永远不会碰到

无法读取未定义的属性“名称”。

你基本上检查user是否存在,如果不存在,你立即创建一个空对象。这样,下一层键将始终从一个存在的对象或空对象访问,而不会从undefined访问。

2. 使用数组缩减访问嵌套对象

为了能够访问嵌套数组,您可以编写自己的数组reduce util。

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// this will return the city from the first address item.

还有一种出色的类型处理最小库类型可以为您完成所有这些。