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

例如:

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

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


当前回答

动态访问多级对象。

var obj = {
  name: "john doe",
  subobj: {
    subsubobj: {
      names: "I am sub sub obj"
    }
  }
};

var level = "subobj.subsubobj.names";
level = level.split(".");

var currentObjState = obj;

for (var i = 0; i < level.length; i++) {
  currentObjState = currentObjState[level[i]];
}

console.log(currentObjState);

工作提琴:https://jsfiddle.net/andreitodorut/3mws3kjL/

其他回答

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

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演示。

在2020年,你可以使用@babel/plugin-proposal-optional- chains,它很容易访问对象中的嵌套值。

 const obj = {
 foo: {
   bar: {
     baz: class {
   },
  },
 },
};

const baz = new obj?.foo?.bar?.baz(); // baz instance

const safe = new obj?.qux?.baz(); // undefined
const safe2 = new obj?.foo.bar.qux?.(); // undefined

https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining

https://github.com/tc39/proposal-optional-chaining

这里有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);

使用lodash是一个很好的解决方案

例:

var object = { 'a': { 'b': { 'c': 3 } } };                                                                                               
_.get(object, 'a.b.c');                                                                                             
// => 3  
// const path = 'info.value[0].item'
// const obj = { info: { value: [ { item: 'it works!' } ], randominfo: 3 }  }
// getValue(path, obj)

export const getValue = ( path , obj) => {
  const newPath = path.replace(/\]/g, "")
  const arrayPath = newPath.split(/[\[\.]+/) || newPath;

  const final = arrayPath.reduce( (obj, k) => obj ?  obj[k] : obj, obj)
  return final;
}