如何在目录树JSON文件中高效获取指定文档的路径?
Hey there! Let's tackle this problem head-on—your current layer-by-layer traversal approach is slow, hard to maintain, and won't handle directory changes gracefully. The key fix here is to pre-build a reverse lookup map that lets you jump straight from a filename to its full path, no more tedious tree traversal every time a user searches.
The Core Solution: Reverse Path Mapping
Instead of crawling the entire directory tree for every user input, do a single pass over your JSON tree once (or whenever the tree updates) to create a simple key-value object. Each key is a filename, and the value is its full path starting from the documents/ root. This turns every lookup into an O(1) operation—blazingly fast.
Here's a straightforward JavaScript implementation:
// Example JSON directory tree (match your actual structure) const directoryTree = { name: "documents", type: "folder", children: [ { name: "customer 555", type: "folder", children: [ { name: "product 1", type: "folder", children: [ { name: "product 1.2", type: "folder", children: [ { name: "document 8", type: "folder", children: [ { name: "48555 001 00-8.pdf", type: "file" } ] } ] } ] } ] } ] }; // Build a filename-to-full-path lookup map function buildFilePathLookup(tree, currentPath = "") { const lookup = {}; // Construct the full path for the current node const fullNodePath = currentPath ? `${currentPath}/${tree.name}` : tree.name; if (tree.type === "file") { // Add file to the lookup map lookup[tree.name] = fullNodePath; } else if (tree.children?.length) { // Recursively process child folders tree.children.forEach(child => { Object.assign(lookup, buildFilePathLookup(child, fullNodePath)); }); } return lookup; } // Generate the lookup map (run once on app load or when the directory tree updates) const fileLookup = buildFilePathLookup(directoryTree); // Quick lookup example for user input const userInput = "48555 001 00-8.pdf"; if (fileLookup[userInput]) { const apacheUrl = `localhost/${fileLookup[userInput]}`; console.log(apacheUrl); // Output: localhost/documents/customer 555/product 1/product 1.2/document 8/48555 001 00-8.pdf } else { console.log("Document not found in directory tree"); }
Handling Directory Changes
When your structure updates (new folders, moved files, deleted docs), just re-run buildFilePathLookup to refresh the map. For large trees, you can optimize this by only reprocessing the changed branch instead of the entire tree, but even a full re-run is way faster than traversing the tree for every user search.
Note on Duplicate Filenames
If you ever have duplicate filenames (unlikely with your document numbering scheme), modify the lookup to store an array of paths instead of a single string:
if (tree.type === "file") { if (lookup[tree.name]) { lookup[tree.name].push(fullNodePath); } else { lookup[tree.name] = [fullNodePath]; } }
JavaScript Libraries (If You Want to Avoid Rolling Your Own)
For most cases, the custom code above is lightweight and flexible enough. But if you need advanced tree operations (dynamic node edits, path validation, etc.), consider these options:
- Lodash: Use
_.flatMapDeepor_.reduceto simplify tree traversal (though adding Lodash just for this is overkill). - Treeify: A small utility for working with tree structures, but your use case is simple enough that custom code is more efficient.
The reverse map approach eliminates messy layer-by-layer traversal, speeds up lookups to near-instant, and adapts seamlessly to directory changes—perfect for your use case.
内容的提问来源于stack exchange,提问作者Milo

