如何用Lodash从子节点回溯至根节点并生成路径
Let's solve this problem step by step. You're right that a single _.find() call only gets one parent level—we need to loop backward through the tree until we hit the root node (parent_id: 0), then build up all the required path variations.
Approach
- Locate the target node: Start with the specific child node you want to trace from (in your case,
SubFolder1withid:4). - Backtrack to the root: Keep collecting each node's
class_nameas we move up to its parent, stopping only when we reach the root (whereparent_id:0). - Reverse collected segments: Since we gather names from child to root, reversing gives us the natural root-to-child order.
- Generate incremental paths: Create paths by taking progressively longer prefixes of the reversed segments (starting with just the child, then parent/child, then full root-to-child path).
Implementation (Pure JavaScript)
First, let's work with your existing tree data:
const tree = [ { id: 1, class_name: 'Home', parent_id: 0 }, { id: 2, class_name: 'Folder1', parent_id: 1 }, { id: 3, class_name: 'Folder2', parent_id: 1 }, { id: 4, class_name: 'SubFolder1', parent_id: 2 }, { id: 5, class_name: 'EndFolder1', parent_id: 4 } ];
Here's a reusable function to generate the required paths:
function generateBacktrackPaths(tree, targetNodeId) { // Step 1: Find the starting node let currentNode = tree.find(node => node.id === targetNodeId); if (!currentNode) return []; // Handle case where node doesn't exist // Step 2: Collect segments from child to root const pathSegments = []; while (currentNode) { pathSegments.push(currentNode.class_name); // Stop when we reach root, or move to parent node if (currentNode.parent_id === 0) break; currentNode = tree.find(node => node.id === currentNode.parent_id); } // Step 3: Reverse to get root-to-child order const rootToChildSegments = pathSegments.reverse(); // Step 4: Generate all incremental path variations const paths = []; for (let i = rootToChildSegments.length - 1; i >= 0; i--) { paths.push(rootToChildSegments.slice(i).join('/')); } return paths; } // Usage example const result = generateBacktrackPaths(tree, 4); console.log(result); // Output: ["SubFolder1", "Folder1/SubFolder1", "Home/Folder1/SubFolder1"]
Implementation with Lodash
If you prefer using Lodash for cleaner lookups, replace the native find with _.find:
const _ = require('lodash'); function generateBacktrackPathsWithLodash(tree, targetNodeId) { let currentNode = _.find(tree, { id: targetNodeId }); if (!currentNode) return []; const pathSegments = []; while (currentNode) { pathSegments.push(currentNode.class_name); if (currentNode.parent_id === 0) break; currentNode = _.find(tree, { id: currentNode.parent_id }); } const rootToChildSegments = pathSegments.reverse(); const paths = []; for (let i = rootToChildSegments.length - 1; i >= 0; i--) { paths.push(rootToChildSegments.slice(i).join('/')); } return paths; } // Usage const result = generateBacktrackPathsWithLodash(tree, 4); console.log(result); // Same output as above
Key Fixes from Your Original Code
Your initial snippet only checked one parent level—this solution uses a while loop to keep traversing upward until we hit the root, ensuring we collect all necessary nodes to build the full path set.
内容的提问来源于stack exchange,提问作者Nidhin Kumar
相关产品推荐
相关产品推荐

