JavaScript新手求助:如何将对象数组转换为树形JSON结构
Hey there! No worries at all—we all start somewhere when working with JavaScript objects and tree structures. Let's walk through exactly how to convert your flat array into a nested tree JSON structure.
First, let's clarify the core goal: your array has objects with hierarchical levels (l1 to l6), where null means no deeper level exists. We want to turn this into a nested tree where each node has an id and a children array for its sub-nodes.
Tailored Solution for Your Data
function buildTree(data) { // Initialize root node since all your entries use l1 = 1 as the top level const root = { id: 1, children: [] }; data.forEach(item => { // Extract all non-null level values to form the path for this entry const levels = [item.l1, item.l2, item.l3, item.l4, item.l5, item.l6].filter(val => val !== null); let currentNode = root; // Start from the second level (root is already l1) for (let i = 1; i < levels.length; i++) { const levelId = levels[i]; // Check if this node already exists in the current parent's children let childNode = currentNode.children.find(child => child.id === levelId); // Create and add the node if it doesn't exist if (!childNode) { childNode = { id: levelId, children: [] }; currentNode.children.push(childNode); } // Move down to the child node for the next iteration currentNode = childNode; } }); return root; } // Your original dataset const originalData = [ { "l1": 1, "l2": 2, "l3": 3, "l4": 4, "l5": 5, "l6": null }, { "l1": 1, "l2": 2, "l3": 3, "l4": 4, "l5": 6, "l6": null }, { "l1": 1, "l2": 2, "l3": 7, "l4": 8, "l5": 9, "l6": null }, { "l1": 1, "l2": 2, "l3": 7, "l4": 8, "l5": 10, "l6": null }, { "l1": 1, "l2": 2, "l3": 3, "l4": 11, "l5": 12, "l6": null }, { "l1": 1, "l2": 2, "l3": 3, "l4": 11, "l5": 13, "l6": null } ]; // Generate and log the tree const tree = buildTree(originalData); console.log(JSON.stringify(tree, null, 2));
How This Code Works
- Root Initialization: We start by creating a root node with
id: 1since every entry in your data uses this as the top-level parent. - Path Extraction: For each object, we pull out all non-null level values to form a clear hierarchy path (e.g., the first entry's path is
[1,2,3,4,5]). - Node Traversal & Creation: We start at the root and work our way down each level of the path:
- Check if the node already exists in the current parent's
childrenarray. - If it doesn't exist, create a new node and add it to the parent's children.
- Move to this child node to handle the next level in the path.
- Check if the node already exists in the current parent's
Resulting Tree Structure
When you run the code, you'll get this clean, nested JSON:
{ "id": 1, "children": [ { "id": 2, "children": [ { "id": 3, "children": [ { "id": 4, "children": [ { "id": 5, "children": [] }, { "id": 6, "children": [] } ] }, { "id": 11, "children": [ { "id": 12, "children": [] }, { "id": 13, "children": [] } ] } ] }, { "id": 7, "children": [ { "id": 8, "children": [ { "id": 9, "children": [] }, { "id": 10, "children": [] } ] } ] } ] } ] }
Bonus: Generic Version for Multiple Root Nodes
If your data ever has multiple values for l1, here's a flexible version that handles any number of root nodes:
function buildGenericTree(data) { const nodeMap = new Map(); const roots = []; data.forEach(item => { const levels = [item.l1, item.l2, item.l3, item.l4, item.l5, item.l6].filter(val => val !== null); levels.forEach((id, index) => { // Create node if it doesn't exist if (!nodeMap.has(id)) { nodeMap.set(id, { id, children: [] }); } const currentNode = nodeMap.get(id); // Add to roots if it's the first level (avoid duplicates) if (index === 0) { if (!roots.includes(currentNode)) { roots.push(currentNode); } } else { // Add current node to its parent's children (avoid duplicates) const parentId = levels[index - 1]; const parentNode = nodeMap.get(parentId); if (!parentNode.children.includes(currentNode)) { parentNode.children.push(currentNode); } } }); }); return roots; }
This version uses a Map to track all nodes, ensuring no duplicates and easy parent lookups.
内容的提问来源于stack exchange,提问作者anoop chandran

