我遇到了将简单的平面数据转换为分层的常见问题。我已经找到了关于这个的多个主题,但仍然无法获得如何将平面数据完全转换为必要的分层格式
这是我的json
[
{
"id": 1,
"name": "Sponsor",
"description": null,
"parentId": null
},
{
"id": 2,
"name": "Class",
"description": null,
"parentId": 1
},
{
"id": 3,
"name": "Study",
"description": null,
"parentId": 2
},
{
"id": 4,
"name": "Site",
"description": null,
"parentId": 3
}
]
我需要获得这样的格式
[
{
"data":{
"id": 1,
"name":"Sponsor",
"description":null,
"parentId":"null"
},
"children":[
{
"data":{
"id": 2,
"name":"Class",
"description":null,
"parentId":"1"
},
"children":[
{
"data":{
"id": 3,
"name":"Study",
"description":null,
"parentId":"2"
},
"children": [
{
"data":{
"id": 4,
"name":"Site",
"description":null,
"parentId":"3"
}
}
]
}
]
}
]
}
]
这是我的功能
flatToHierarchy(flat) {
let roots = [];
let all = {};
flat.forEach(function (item) {
all[item.id] = item
});
Object.keys(all).forEach(function (id) {
let item = all[id];
if (item.parentId === null) {
roots.push(item)
} else if (item.parentId in all) {
let p = all[item.parentId];
if (!('Children' in p)) {
p.children = []
}
p.children.push(item)
}
});
console.log(roots);
return roots
}
输出
[
{
"id": 1,
"name": "Sponsor",
"description": null,
"parentId": null,
"children": [
{
"id": 2,
"name": "Class",
"description": "Together",
"parentId": 1,
"children": [
{
"id": 3,
"name": "Study",
"description": "browsing data",
"parentId": 2,
"children": [
{
"id": 4,
"name": "Site",
"description": null,
"parentId": 3,
"children": []
}
]
}
]
}
]
}
]
我非常接近渴望的结果。有人可以帮我解决这个问题吗?
被修改
@ Someone3 提供的正确答案 这是针对我的需求略微修改的代码
flatToHierarchy (flat) {
let roots = [];
let all = {};
let ids = [];
flat.forEach(function (item) {
let itemId = item.id;
let convertedItem = function (id) {
let newItem = {};
newItem['data'] = id;
return newItem;
} ;
all[itemId] = convertedItem(item);
ids.push(itemId);
});
for (let i = 0; i < ids.length; i++) {
let id = ids[i];
let convertedItem = all[id];
let parentId = convertedItem.data.parentId;
if (parentId === null) {
roots.push(convertedItem);
} else if (parentId in all) {
let p = all[parentId];
if (!('children' in p)) {
p.children = []
}
p.children.push(convertedItem)
}
}
return roots
}
答案 0 :(得分:1)
以下代码是您的具体情况的完整源代码。我修改并添加了源代码中的几行。 请注意,此代码假定父项在其子项之前始终插入此树。如果此假设并非总是如此,那么您的代码需要进行更改。
let flatData = [
{
"id": 1,
"name": "Sponsor",
"description": null,
"parentId": null
},
{
"id": 2,
"name": "Class",
"description": null,
"parentId": 1
},
{
"id": 3,
"name": "Study",
"description": null,
"parentId": 2
},
{
"id": 4,
"name": "Site",
"description": null,
"parentId": 3
}
];
function convertItem(item) {
let newItem = {};
newItem.data = item;
return newItem;
}
function flatToHierarchy(flat) {
let roots = [];
let all = {};
let ids = [];
flat.forEach(function (item) {
let itemId = item.id;
let convertedItem = convertItem(item);
all[itemId] = convertedItem;
ids.push(itemId);
});
// We use ids array instead of object to maintain its previous order.
for (let i = 0; i < ids.length; i++) {
let id = ids[i];
let convertedItem = all[id];
let parentId = convertedItem.data.parentId;
if (parentId === null) {
delete convertedItem.data.parentId;
delete convertedItem.data.id;
roots.push(convertedItem);
} else if (parentId in all) {
let p = all[parentId];
if (!('Children' in p)) {
p.children = []
}
delete convertedItem.data.parentId;
delete convertedItem.data.id;
p.children.push(convertedItem)
}
};
console.log(roots);
return roots
}
flatToHierarchy(flatData);
我们可以在推送之前分解两个删除。
答案 1 :(得分:0)
我的方式如何?
function flatToHierarchy (flatData) {
const tree = JSON.parse(JSON.stringify(flatData)) // or using `cloneDeep` of lodash library to not side-effect with flatData
tree.forEach((item) => {
item.children = tree.filter((element) => element.parent_id === dept.id)
});
const roots = tree.filter((item) => item.parent_id === 0)
return roots
}