[英]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.