admin管理员组文章数量:1394396
I have the following valid JSON. It describes a tree structure:
{
"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"
}
]
}
I need to be able to get any of the "items" by id and any of the child items. For example. Initially I tried grep:
var returnedData = $.grep(obj.items, function(element, index){return element.id == "2";
});
This worked great for item with id==2 but fails pletely when I try to obtain element.id=="7"
Any assistance would be appreciated. Thanks in advance.
I have the following valid JSON. It describes a tree structure:
{
"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"
}
]
}
I need to be able to get any of the "items" by id and any of the child items. For example. Initially I tried grep:
var returnedData = $.grep(obj.items, function(element, index){return element.id == "2";
});
This worked great for item with id==2 but fails pletely when I try to obtain element.id=="7"
Any assistance would be appreciated. Thanks in advance.
Share Improve this question asked May 4, 2014 at 18:51 user831839user831839 2473 silver badges6 bronze badges3 Answers
Reset to default 5You can make a recursive function to search in the data:
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);
Demo: http://jsfiddle/rj26H/
In this function I just looped over the object, so its a bit more verbose. You could probably also use $.grep to do the searching and make the code a bit smaller. Anyway, the trick is to search all children if the item is not found on the main level. Apparently grep
doesn't work in a recursive fashion.
Try this:
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);
Demo Link
I know this have been already answered, but I wanted to show how you could leverage the new the new JavaScript 1.7 features to solve this. Please note that the same approach could have been used without support for generators, but the code would have been longer.
//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"}
Note that you can also set the __iterator__
on the data structure so that functions that needs to iterate over this data structure do not have to know implementation details.
tree.__iterator__ = treeIterator.bind(null, tree,
function (node, i) { return node.children[i]; },
function (node) { return node.children? node.children.length : 0; }
);
Then the findNodeById
function can be:
function findNodeById(tree, id) {
for (let node in it) if (node.id === id) return node;
return null;
}
本文标签: javascriptNested JSON find itemStack Overflow
版权声明:本文标题:javascript - Nested JSON find item - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744075004a2586582.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论