创建递归 JSON 层次结构树时出现问题
我有平面文件格式的输入数据。我已经编写了 javascript 代码来创建递归层次结构 JSON 树。我没有得到预期的树(下面突出显示为预期输出)。谁能帮助我理解我可能出错的地方?
注意:输入数据中如果没有child_id则表示它是叶子节点。
用代码输入数据
var data=[
{"Type":"Root","url":"abc","description":"Enterprise Risk Management Framework","id":0,"child_id":3},
{"Type":"Stem","url":"def","description":"Risk Governance Framework","id":3,"child_id":4},
{"Type":"Stem","url":"def","description":"Risk Governance Framework","id":3,"child_id":9},
{"Type":"Stem","url":"def","description":"Risk Governance Framework","id":3,"child_id":11},
{"Type":"Stem","url":"ghi","description":"Wholesale Credit Risk framework","id":4,"child_id":6},
{"Type":"Stem","url":"jkl","description":"Wholesale Credit Risk Policy","id":6,"child_id":7},
{"Type":"Stem","url":"jkl","description":"Wholesale Credit Risk Policy","id":6,"child_id":8},
{"Type":"Leaf","url":"mno","description":"Wholesale Credit In-Business Quality Assurance Standard","id":7},
{"Type":"Leaf","url":"pqr","description":"WCR Exception Management Standard","id":8},
{"Type":"Stem","url":"stu","description":"Global Collateral Management Policy","id":9,"child_id":10},
{"Type":"Leaf","url":"gov","description":"WCR Collateral Management Standard","id":10},
{"Type":"Stem","url":"iit","description":"Real Estate Appraisal and Valuation Policy","id":11,"child_id":12},
{"Type":"Stem","url":"iim","description":"Commercial Real Estate Appraisal/Valuation Standard","id":12,"child_id":13},
{"Type":"Leaf","url":"har","description":"Commercial Real Estate Appraisal/Valuation Procedures","id":13}
]
// Given a parent ID, find and return the item in the data with that ID
const findParent = parentId => data.find(item => item.child_id === parentId)
// Create the tree by reducing the data to a root list
// that only contains "orphans". Items that do have a
// parent will be appended to those orphans' child lists
// instead
const tree = data.reduce((root, item) => {
// Find the parent of the current item
const parent = findParent(item.id)
if (parent) {
// If a parent was found, append the current item
// to the parent's child list. Since objects are
// passed by reference, it doesn't matter whether
// the parent is already in the root list or not
// -- it always points to the same object
parent.children = parent.children || []
parent.children.push(item)
} else {
// Otherwise push the item to the root list
root.push(item)
}
return root
}, [])
console.log(JSON.stringify(tree));
当前输出
[
{
"Type": "Root",
"url": "abc",
"description": "Enterprise Risk Management Framework",
"id": 0,
"child_id": 3,
"children": [
{
"Type": "Stem",
"url": "def",
"description": "Risk Governance Framework",
"id": 3,
"child_id": 4,
"children": [
{
"Type": "Stem",
"url": "mno",
"description": "Wholesale Credit Risk Framework",
"id": 4,
"child_id": 6,
"children": [
{
"Type": "Stem",
"url": "pqr",
"description": "Wholesale Credit Risk Policy",
"id": 6,
"child_id": 7,
"children": [
{
"Type": "Leaf",
"url": "vwx",
"description": "Wholesale Credit In-Business Quality Assurance Standard",
"id": 7
}
]
},
{
"Type": "Stem",
"url": "stu",
"description": "Wholesale Credit Risk Policy",
"id": 6,
"child_id": 8,
"children": [
{
"Type": "Leaf",
"url": "zab",
"description": "WCR Exception Management Standard",
"id": 8
}
]
}
]
}
]
},
{
"Type": "Stem",
"url": "ghi",
"description": "Risk Governance Framework",
"id": 3,
"child_id": 9,
"children": [
{
"Type": "Stem",
"url": "nsr",
"description": "Global Collateral Management Policy",
"id": 9,
"child_id": 10,
"children": [
{
"Type": "Leaf",
"url": "gov",
"description": "WCR Collateral Management Standard",
"id": 10
}
]
}
]
},
{
"Type": "Stem",
"url": "jkl",
"description": "Risk Governance Framework",
"id": 3,
"child_id": 11,
"children": [
{
"Type": "Stem",
"url": "iit",
"description": "Real Estate Appraisal and Valuation Policy",
"id": 11,
"child_id": 12,
"children": [
{
"Type": "Stem",
"url": "iim",
"description": "Commercial Real Estate Appraisal/Valuation Standard",
"id": 12,
"child_id": 13,
"children": [
{
"Type": "Leaf",
"url": "har",
"description": "Commercial Real Estate Appraisal/Valuation Procedures",
"id": 13
}
]
}
]
}
]
}
]
}
]
预期输出
{
"id": 0,
"type": "Root",
"description": "Enterprise Risk Management Framework",
"url": "abc",
"children": [
{
"id": 3,
"type": "Stem",
"description": "Risk Governance Framework",
"url": "def",
"children": [
{
"id": 4,
"type": "Stem",
"description": "Wholesale Credit Risk Framework",
"url": "ghi",
"children": [
{
"id": 6,
"type": "Stem",
"description": "Wholesale Credit Risk Policy",
"url": "jkl",
"children": [
{
"id": 7,
"type": "Leaf",
"description": "Wholesale Credit In-Business Quality Assurance Standard",
"url": "mno",
"children": [
]
},
{
"id": 8,
"type": "Leaf",
"description": "WCR Exception Management Standard",
"url": "pqr",
"children": [
]
}
]
}
]
},
{
"id": 9,
"type": "Stem",
"description": "Global Collateral Management Policy",
"url": "stu",
"children": [
{
"id": 10,
"type": "Leaf",
"description": "WCR Collateral Management Standard",
"url": "gov",
"children": [
]
}
]
},
{
"id": 11,
"type": "Stem",
"description": "Real Estate Appraisal and Valuation Policy",
"url": "iit",
"children": [
{
"id": 12,
"type": "Stem",
"description": "Commercial Real Estate Appraisal/Valuation Standard",
"url": "iim",
"children": [
{
"id": 13,
"type": "Leaf",
"description": "Commercial Real Estate Appraisal/Valuation Procedures",
"url": "har",
"children": [
]
}
]
}
]
}
]
}
]
}
I have input data in flatfile format. I have written my javascript code to create recursive hierarchy JSON tree. I am not getting expected tree (highlighted below as expected output). Can anyone please help me understand where I might be going wrong?
Note: In input data if there is no child_id it means it is leaf node.
Input data with code
var data=[
{"Type":"Root","url":"abc","description":"Enterprise Risk Management Framework","id":0,"child_id":3},
{"Type":"Stem","url":"def","description":"Risk Governance Framework","id":3,"child_id":4},
{"Type":"Stem","url":"def","description":"Risk Governance Framework","id":3,"child_id":9},
{"Type":"Stem","url":"def","description":"Risk Governance Framework","id":3,"child_id":11},
{"Type":"Stem","url":"ghi","description":"Wholesale Credit Risk framework","id":4,"child_id":6},
{"Type":"Stem","url":"jkl","description":"Wholesale Credit Risk Policy","id":6,"child_id":7},
{"Type":"Stem","url":"jkl","description":"Wholesale Credit Risk Policy","id":6,"child_id":8},
{"Type":"Leaf","url":"mno","description":"Wholesale Credit In-Business Quality Assurance Standard","id":7},
{"Type":"Leaf","url":"pqr","description":"WCR Exception Management Standard","id":8},
{"Type":"Stem","url":"stu","description":"Global Collateral Management Policy","id":9,"child_id":10},
{"Type":"Leaf","url":"gov","description":"WCR Collateral Management Standard","id":10},
{"Type":"Stem","url":"iit","description":"Real Estate Appraisal and Valuation Policy","id":11,"child_id":12},
{"Type":"Stem","url":"iim","description":"Commercial Real Estate Appraisal/Valuation Standard","id":12,"child_id":13},
{"Type":"Leaf","url":"har","description":"Commercial Real Estate Appraisal/Valuation Procedures","id":13}
]
// Given a parent ID, find and return the item in the data with that ID
const findParent = parentId => data.find(item => item.child_id === parentId)
// Create the tree by reducing the data to a root list
// that only contains "orphans". Items that do have a
// parent will be appended to those orphans' child lists
// instead
const tree = data.reduce((root, item) => {
// Find the parent of the current item
const parent = findParent(item.id)
if (parent) {
// If a parent was found, append the current item
// to the parent's child list. Since objects are
// passed by reference, it doesn't matter whether
// the parent is already in the root list or not
// -- it always points to the same object
parent.children = parent.children || []
parent.children.push(item)
} else {
// Otherwise push the item to the root list
root.push(item)
}
return root
}, [])
console.log(JSON.stringify(tree));
Current Output
[
{
"Type": "Root",
"url": "abc",
"description": "Enterprise Risk Management Framework",
"id": 0,
"child_id": 3,
"children": [
{
"Type": "Stem",
"url": "def",
"description": "Risk Governance Framework",
"id": 3,
"child_id": 4,
"children": [
{
"Type": "Stem",
"url": "mno",
"description": "Wholesale Credit Risk Framework",
"id": 4,
"child_id": 6,
"children": [
{
"Type": "Stem",
"url": "pqr",
"description": "Wholesale Credit Risk Policy",
"id": 6,
"child_id": 7,
"children": [
{
"Type": "Leaf",
"url": "vwx",
"description": "Wholesale Credit In-Business Quality Assurance Standard",
"id": 7
}
]
},
{
"Type": "Stem",
"url": "stu",
"description": "Wholesale Credit Risk Policy",
"id": 6,
"child_id": 8,
"children": [
{
"Type": "Leaf",
"url": "zab",
"description": "WCR Exception Management Standard",
"id": 8
}
]
}
]
}
]
},
{
"Type": "Stem",
"url": "ghi",
"description": "Risk Governance Framework",
"id": 3,
"child_id": 9,
"children": [
{
"Type": "Stem",
"url": "nsr",
"description": "Global Collateral Management Policy",
"id": 9,
"child_id": 10,
"children": [
{
"Type": "Leaf",
"url": "gov",
"description": "WCR Collateral Management Standard",
"id": 10
}
]
}
]
},
{
"Type": "Stem",
"url": "jkl",
"description": "Risk Governance Framework",
"id": 3,
"child_id": 11,
"children": [
{
"Type": "Stem",
"url": "iit",
"description": "Real Estate Appraisal and Valuation Policy",
"id": 11,
"child_id": 12,
"children": [
{
"Type": "Stem",
"url": "iim",
"description": "Commercial Real Estate Appraisal/Valuation Standard",
"id": 12,
"child_id": 13,
"children": [
{
"Type": "Leaf",
"url": "har",
"description": "Commercial Real Estate Appraisal/Valuation Procedures",
"id": 13
}
]
}
]
}
]
}
]
}
]
expected Output
{
"id": 0,
"type": "Root",
"description": "Enterprise Risk Management Framework",
"url": "abc",
"children": [
{
"id": 3,
"type": "Stem",
"description": "Risk Governance Framework",
"url": "def",
"children": [
{
"id": 4,
"type": "Stem",
"description": "Wholesale Credit Risk Framework",
"url": "ghi",
"children": [
{
"id": 6,
"type": "Stem",
"description": "Wholesale Credit Risk Policy",
"url": "jkl",
"children": [
{
"id": 7,
"type": "Leaf",
"description": "Wholesale Credit In-Business Quality Assurance Standard",
"url": "mno",
"children": [
]
},
{
"id": 8,
"type": "Leaf",
"description": "WCR Exception Management Standard",
"url": "pqr",
"children": [
]
}
]
}
]
},
{
"id": 9,
"type": "Stem",
"description": "Global Collateral Management Policy",
"url": "stu",
"children": [
{
"id": 10,
"type": "Leaf",
"description": "WCR Collateral Management Standard",
"url": "gov",
"children": [
]
}
]
},
{
"id": 11,
"type": "Stem",
"description": "Real Estate Appraisal and Valuation Policy",
"url": "iit",
"children": [
{
"id": 12,
"type": "Stem",
"description": "Commercial Real Estate Appraisal/Valuation Standard",
"url": "iim",
"children": [
{
"id": 13,
"type": "Leaf",
"description": "Commercial Real Estate Appraisal/Valuation Procedures",
"url": "har",
"children": [
]
}
]
}
]
}
]
}
]
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以在
Map
中收集id和相应的目标对象。最初,每个对象的children
属性将为空。然后再次迭代数据以查找给定id
的对象和给定child_id
的对象,并将后一个对象放入children
数组中前者的。最后,获取根对象,假设id为0。
代码:
You could collect the id and corresponding target object in a
Map
. Initially thechildren
property of each object will be empty. Then iterate the data again to lookup the object for a givenid
and the object for the givenchild_id
and put the latter object into thechildren
array of the former.Finally, get the root object which is assumed to have id 0.
Code:
以下是基于此答案的示例。我已重构您的数据以使用 id/parentId。我已经删除了重复项/不重复项(树的每个元素在数据集中实际上只需要 1 个东西,无论它有多少个子元素)。
Here's an example based on this answer. I have refactored your data to use id/parentId. I have removed the duplicates/not duplicates (you only really need 1 thing in the dataset per element of the tree, no matter how many children it has).