[英]Building tree from JSON data
我正在尝试构建一个递归嵌套每个项目的 JSON 树结构,目前我有这个:
var data = [ { "id":"", "items":[ { "fullName":"images", "name":"images", "type":"folder", "dateCreated":1578270119240, "updatedDate":1583448360597 }, { "fullName":"media", "name":"media", "type":"folder", "dateCreated":1578270119445, "updatedDate":1583383567345 } ] }, { "id":"images", "items":[ { "fullName":"images/123123", "name":"123123", "type":"folder", "dateCreated":1578270119244, "updatedDate":1583384536404 }, { "fullName":"images/banners", "name":"banners", "type":"folder", "dateCreated":1578270119257, "updatedDate":1583384536407 }, { "fullName":"images/doodle", "name":"doodle", "type":"folder", "dateCreated":1578270119441, "updatedDate":1583384536421 } ] }, { "id":"media", "items":[ { "fullName":"media/123123", "name":"123123", "type":"folder", "dateCreated":1578270119244, "updatedDate":1583384536404 }, { "fullName":"media/banners", "name":"banners", "type":"folder", "dateCreated":1578270119257, "updatedDate":1583384536407 }, { "fullName":"media/doodle", "name":"doodle", "type":"folder", "dateCreated":1578270119441, "updatedDate":1583384536421 } ] }, { "id":"media/123123", "items":[ { "fullName":"media/123123/1000", "name":"1000", "type":"folder", "dateCreated":1578270119244, "updatedDate":1583384536404 } ] } ]; console.log( buildHierarchy(data) ); function buildHierarchy(arry) { var roots = [], items = {}; for(var i = 0, len = arry.length ; i < len; i++) { var item = arry[i], p = item.id; target = !p ? roots : (items[p] || (items[p] = [])); target.push({id : item.id, items : item.items }) } var findChildren = function(parent) { for (var j = 0, len = parent.items.length; j < len; j++) { if(items[parent.items[j].fullName]) { parent.items[j].items = items[parent.items[j].fullName]; //console.log(parent.items[j].items); findChildren(parent.items[j]); } } } for (var i = 0, len = roots.length; i < len; i++) { findChildren(roots[i]) } return roots; }
它嵌套了大部分数据,但似乎错过了我希望创建的节点之一,我无法弄清楚我应该递归调用什么以便创建所有节点。 我希望像这样显示数据:
[
{
"id":"",
"items":[
{
"id":"images",
"fullName":"images",
"name":"images",
"type":"folder",
"dateCreated":1578270119240,
"updatedDate":1583448360597,
"items":[
{
"id":"images/123123",
"fullName":"images/123123",
"name":"123123",
"type":"folder",
"dateCreated":1578270119244,
"updatedDate":1583384536404,
"items":[
]
},
{
"id":"images/banners",
"fullName":"images/banners",
"name":"banners",
"type":"folder",
"dateCreated":1578270119257,
"updatedDate":1583384536407,
"items":[
]
},
{
"id":"images/doodle",
"fullName":"images/doodle",
"name":"doodle",
"type":"folder",
"dateCreated":1578270119441,
"updatedDate":1583384536421,
"items":[
]
}
]
},
{
"id":"media",
"fullName":"media",
"name":"media",
"type":"folder",
"dateCreated":1578270119445,
"updatedDate":1583383567345,
"items":[
{
"fullName":"media/123123",
"name":"123123",
"type":"folder",
"dateCreated":1578270119244,
"updatedDate":1583384536404,
"items":[
{
"id":"media/123123",
"items":[
{
"fullName":"media/123123/1000",
"name":"1000",
"type":"folder",
"dateCreated":1578270119244,
"updatedDate":1583384536404
}
]
}
]
}
]
}
]
最简单的方法是创建一个递归函数,从"id": ""
。 然后,您可以使用在数据数组中找到的完整元数据来充实每个项目节点。 如果该函数是递归的并且具有适当的停止检查,那么您应该能够任意深度地跟随树。
唯一的缺点是,如果根节点中有一个"id": "foo"
而没有对应的"name": "foo"
,那么它将被排除在你的树之外。 我将假设这是不可能的,但这是需要注意的。
function findNode(id){
return data.find(e => e.id === id);
}
function buildHierarchy(node) {
if (!node) return;
const items = node.items || [];
for (item of items) {
// Append the information in the item with the
// corresponding node in the data array, including
// the item's items array. This is the recursive
// part. We keep walking down the tree until we
// can't find an item's "full info node" in the
// data array.
const fullInfoNode = findNode(item.fullName);
Object.assign(item, buildHierarchy(fullInfoNode));
}
return node;
}
buildHierarchy(findNode(""))
function findNode(id){ return data.find(e => e.id === id); } function buildHierarchy(node) { if (!node) return; const items = node.items || []; for (item of items) { const fullInfoNode = findNode(item.fullName); Object.assign(item, buildHierarchy(fullInfoNode)); } return node; } var data = [ { "id":"", "items":[ { "fullName":"images", "name":"images", "type":"folder", "dateCreated":1578270119240, "updatedDate":1583448360597 }, { "fullName":"media", "name":"media", "type":"folder", "dateCreated":1578270119445, "updatedDate":1583383567345 } ] }, { "id":"images", "items":[ { "fullName":"images/123123", "name":"123123", "type":"folder", "dateCreated":1578270119244, "updatedDate":1583384536404 }, { "fullName":"images/banners", "name":"banners", "type":"folder", "dateCreated":1578270119257, "updatedDate":1583384536407 }, { "fullName":"images/doodle", "name":"doodle", "type":"folder", "dateCreated":1578270119441, "updatedDate":1583384536421 } ] }, { "id":"media", "items":[ { "fullName":"media/123123", "name":"123123", "type":"folder", "dateCreated":1578270119244, "updatedDate":1583384536404 }, { "fullName":"media/banners", "name":"banners", "type":"folder", "dateCreated":1578270119257, "updatedDate":1583384536407 }, { "fullName":"media/doodle", "name":"doodle", "type":"folder", "dateCreated":1578270119441, "updatedDate":1583384536421 } ] }, { "id":"media/123123", "items":[ { "fullName":"media/123123/1000", "name":"1000", "type":"folder", "dateCreated":1578270119244, "updatedDate":1583384536404 } ] } ]; console.log( buildHierarchy(findNode("")) );
请注意,使用此方法,您可以选择所需的任何起始节点。 例如, buildHierarchy(findNode("media"))
将只返回媒体层次结构:
{
"id": "media",
"items": [
{
"fullName": "media/123123",
"name": "123123",
"type": "folder",
"dateCreated": 1578270119244,
"updatedDate": 1583384536404,
"id": "media/123123",
"items": [
{
"fullName": "media/123123/1000",
"name": "1000",
"type": "folder",
"dateCreated": 1578270119244,
"updatedDate": 1583384536404
}
]
},
{
"fullName": "media/banners",
"name": "banners",
"type": "folder",
"dateCreated": 1578270119257,
"updatedDate": 1583384536407
},
{
"fullName": "media/doodle",
"name": "doodle",
"type": "folder",
"dateCreated": 1578270119441,
"updatedDate": 1583384536421
}
]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.