我有一个包含对象和数组的嵌套数据结构。我如何提取信息,即访问一个特定的或多个值(或键)?
例如:
var data = {
code: 42,
items: [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}]
};
我如何访问项目中的第二个项目的名称?
我有一个包含对象和数组的嵌套数据结构。我如何提取信息,即访问一个特定的或多个值(或键)?
例如:
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演示。
其他回答
我不认为提问只关心一个层次的嵌套对象,所以我提出下面的演示来演示如何访问深嵌套json对象的节点。好的,让我们找到id为5的节点。
var data = { 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' }] }] }; var jsonloop = new JSONLoop(data, 'id', 'items'); jsonloop.findNodeById(data, 5, function(err, node) { if (err) { document.write(err); } else { document.write(JSON.stringify(node, null, 2)); } }); <script src="https://rawgit.com/dabeng/JSON-Loop/master/JSONLoop.js"></script>
如果你试图通过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循环会导致代码更容易推理,因此更易于维护。
这只是我的个人意见。
你可以使用lodash _get函数:
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// => 3
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
您可以使用jsonObject语法。键访问该值。如果你想从数组中访问一个值,那么你可以使用jsonObjectArray[index].key语法。
下面是访问各种值的代码示例,可以让您了解这个概念。
Var数据= { 42岁的代码: 项目:[{ id: 1、 名称:“foo” }, { id: 2 名称:“酒吧” }) }; //如果你想要'bar' console.log (data.items [1] . name); //如果你想要数组的项目名称 console.log (data.items。映射(x => x.name)); //获取name = 'bar'的条目id console.log (data.items。过滤(x => (x.name == "bar") ?X.id: null)[0].id);