我有以下有效的JSON。它描述了一个树结构:
{
"items": [
{
"id": "d1"
},
{
"id": "2",
"children": [
{
"id": "3"
},
{
"id": "4"
},
{
"id": "5",
"children": [
{
"id": "6"
},
{
"id": "7",
"children": [
{
"id": "8"
},
{
"id": "9"
}
]
},
{
"id": "10"
}
]
},
{
"id": "11"
},
{
"id": "12"
}
]
},
{
"id": "13"
},
{
"id": "14"
}
]
}
我需要能够通过id和任何子项获取任何“项目”。例如。最初我尝试了grep:
var returnedData = $.grep(obj.items, function(element, index){return element.id == "2";
});
这对于id == 2的项目非常有用,但在我尝试获取element.id ==“7”时完全失败
任何帮助将不胜感激。提前谢谢。
答案 0 :(得分:4)
您可以创建一个递归函数来搜索数据:
function find(source, id)
{
for (key in source)
{
var item = source[key];
if (item.id == id)
return item;
// Item not returned yet. Search its children by recursive call.
if (item.children)
{
var subresult = find(item.children, id);
// If the item was found in the subchildren, return it.
if (subresult)
return subresult;
}
}
// Nothing found yet? return null.
return null;
}
// In the root object, the array of items is called 'items', so we pass in
// data.items to look into. The root object itself doesn't seem to have an id anyway.
var result = find(data.items, 7);
// Show the name of item 7, if it had one...
alert(result.name);
在这个函数中,我只是在对象上循环,所以它有点冗长。您也可以使用$ .grep进行搜索并使代码更小一些。无论如何,诀窍是搜索所有孩子,如果在主级别找不到该项目。显然grep
没有以递归的方式工作。
答案 1 :(得分:1)
试试这个:
var id = 7;
var data = {"items": [{"id": "d1"},{"id": "2","children": [{"id": "3"},{"id": "7"},{"id": "11"},{"id": "12"}]}]};
function search(values) {
$.each(values, function(i, v) {
if (v.id == id) {
console.log('found', v);
return false;
}
if (v.children) {
search(v.children);
}
});
}
search(data.items);
答案 2 :(得分:0)
我知道这已经得到了回答,但我想展示一下如何利用新的JavaScript 1.7 features来解决这个问题。请注意,在不支持生成器的情况下可以使用相同的方法,但代码会更长。
//Returns an iterator that knows how to walk a tree
function treeIterator(root, childGetter, childCountGetter) {
let stack = [root], node;
while (node = stack.pop()) {
yield node;
for (let i = childCountGetter(node); i--;) stack.push(childGetter(node, i));
}
}
//Our custom search function
function findNodeById(tree, id) {
let it = treeIterator(tree,
function (node, i) { return node.children[i]; },
function (node) { return node.children? node.children.length : 0; }
);
for (let node in it) if (node.id === id) return node;
return null;
}
var tree = {
id: 'root',
children: [
{ id: 'a' },
{
id: 'b',
children: [
{ id: 'b1' },
{ id: 'b2' }
]
},
{ id: 'c' }
]
};
findNodeById(tree, 'b1'); //Object { id="b1"}
请注意,您还可以在数据结构上设置__iterator__
,以便需要迭代此数据结构的函数不必知道实现细节。
tree.__iterator__ = treeIterator.bind(null, tree,
function (node, i) { return node.children[i]; },
function (node) { return node.children? node.children.length : 0; }
);
然后findNodeById
函数可以是:
function findNodeById(tree, id) {
for (let node in it) if (node.id === id) return node;
return null;
}