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

例如:

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

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


当前回答

下划线js的方式

这是一个JavaScript库,它提供了一大堆有用的函数式编程助手,而不扩展任何内置对象。

解决方案:

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

var item = _.findWhere(data.items, {
  id: 2
});
if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

//using find - 

var item = _.find(data.items, function(item) {
  return item.id === 2;
});

if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

其他回答

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

动态方法

在下面的deep(data,key)函数中,您可以使用任意键字符串-在您的情况下,items[1].name(您可以在任何级别使用数组符号[i]) -如果key无效,则返回undefined。

让深= (o, k) = > k.split (' . ') .reduce ((a、c、i) = > { 让m = c.match (/(.*?)\[(\ d *) \] /); 如果(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]]; 返回a==null ?答:[c]; }, o); / /测试 Let key = 'items[1].name' //任意深键 Let data = { 42岁的代码: 名称:项目:[{id: 11日“foo”},{id: 22岁的名字:“酒吧”},) }; Console.log (key,'=', deep(data,key));

你可以使用lodash _get函数:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// => 3

下面是一个使用对象扫描的答案。

当访问单个条目时,这个答案并没有提供比普通javascript更多的好处。然而,同时与多个字段交互,这个答案可以更有效。

下面是与单个字段交互的方法

// const objectScan = require('object-scan'); const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] }; const get = (haystack, needle) => objectScan([needle], { abort: true, rtn: 'value' })(haystack); const set = (haystack, needle, value) => objectScan([needle], { abort: true, rtn: 'bool', filterFn: ({ parent, property }) => { parent[property] = value; return true; } })(haystack); console.log(get(data, 'items[1].name')); // => bar console.log(set(data, 'items[1].name', 'foo2')); // => true console.log(data); // => { code: 42, items: [ { id: 1, name: 'foo' }, { id: 2, name: 'foo2' } ] } .as-console-wrapper {max-height: 100% !important; top: 0} <script src="https://bundle.run/object-scan@13.8.0"></script>

声明:我是object-scan的作者

下面是如何同时与多个字段交互

// const objectScan = require('object-scan'); const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] }; const get = (haystack, ...needles) => objectScan(needles, { joined: true, rtn: 'entry' })(haystack); const set = (haystack, actions) => objectScan(Object.keys(actions), { rtn: 'count', filterFn: ({ matchedBy, parent, property }) => { matchedBy.forEach((m) => { parent[property] = actions[m]; }) return true; } })(haystack); console.log(get(data, 'items[0].name', 'items[1].name')); // => [ [ 'items[1].name', 'bar' ], [ 'items[0].name', 'foo' ] ] console.log(set(data, { 'items[0].name': 'foo1', 'items[1].name': 'foo2' })); // => 2 console.log(data); // => { code: 42, items: [ { id: 1, name: 'foo1' }, { id: 2, name: 'foo2' } ] } .as-console-wrapper {max-height: 100% !important; top: 0} <script src="https://bundle.run/object-scan@13.8.0"></script>

声明:我是object-scan的作者


下面是如何在一个深度嵌套的对象中通过id搜索找到一个实体(正如在评论中问到的那样)

// const objectScan = require('object-scan'); const myData = { code: 42, items: [{ id: 1, name: 'aaa', items: [{ id: 3, name: 'ccc' }, { id: 4, name: 'ddd' }] }, { id: 2, name: 'bbb', items: [{ id: 5, name: 'eee' }, { id: 6, name: 'fff' }] }] }; const findItemById = (haystack, id) => objectScan(['**(^items$).id'], { abort: true, useArraySelector: false, rtn: 'parent', filterFn: ({ value }) => value === id })(haystack); console.log(findItemById(myData, 5)); // => { id: 5, name: 'eee' } .as-console-wrapper {max-height: 100% !important; top: 0} <script src="https://bundle.run/object-scan@13.8.0"></script>

声明:我是object-scan的作者

如果你试图通过id或名称从示例结构中访问一个项,而不知道它在数组中的位置,最简单的方法是使用underscore.js库:

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

_.find(data.items, function(item) {
  return item.id === 2;
});
// Object {id: 2, name: "bar"}

根据我的经验,使用高阶函数而不是for或for..in循环会导致代码更容易推理,因此更易于维护。

这只是我的个人意见。