如何将文件路径数组转换为指定格式的Treeview JSON对象?
Problem Description
I need to convert an array of file paths into a treeview JSON structure. Here's my input data:
const data = ["path1/subpath1/file1.doc", "path1/subpath1/file2.doc", "path1/subpath2/file1.doc", "path1/subpath2/file2.doc", "path2/subpath1/file1.doc", "path2/subpath1/file2.doc", "path2/subpath2/file1.doc", "path2/subpath2/file2.doc", "path2/subpath2/additionalpath1/file1.doc"];
The expected output structure (for a single root node example) looks like this:
{ "title": "path1", "childNodes" : [ { "title":"subpath1", "childNodes":[ { "title":"file1.doc", "childNodes":[] }, { "title":"file2.doc", "childNodes":[] } ] }, { "title":"subpath2", "childNodes":[ { "title":"file1.doc", "childNodes":[] }, { "title":"file2.doc", "childNodes":[] } ] } ] }
My current code doesn't produce this format:
let treePath = {}; let formattedData = {}; data.forEach(path => { let levels = path.split("/"); let file = levels.pop(); let prevLevel = treePath; let prevProp = levels.shift(); levels.forEach(prop => { prevLevel[prevProp] = prevLevel[prevProp] || {}; prevLevel = prevLevel[prevProp]; prevProp = prop; }); prevLevel[prevProp] = (prevLevel[prevProp] || []).concat([file]); });
How can I modify this code to get the desired tree structure?
Solution
The issue with your current code is that it uses plain JavaScript objects (key-value pairs) to build the hierarchy, but the target structure requires arrays of node objects (each with title and childNodes properties). Here's a revised approach that builds the tree correctly:
const data = ["path1/subpath1/file1.doc", "path1/subpath1/file2.doc", "path1/subpath2/file1.doc", "path1/subpath2/file2.doc", "path2/subpath1/file1.doc", "path2/subpath1/file2.doc", "path2/subpath2/file1.doc", "path2/subpath2/file2.doc", "path2/subpath2/additionalpath1/file1.doc"]; // Initialize the root of our tree (an array since we have multiple top-level paths: path1, path2) const tree = []; data.forEach(path => { let currentLevel = tree; // Split the path into individual segments const pathSegments = path.split("/"); pathSegments.forEach((segment, index) => { // Check if a node with this title already exists in the current level let existingNode = currentLevel.find(node => node.title === segment); if (!existingNode) { // If no node exists, create a new one with empty childNodes existingNode = { title: segment, childNodes: [] }; currentLevel.push(existingNode); } // Move to the next level of childNodes, unless we're at the last segment (file) if (index !== pathSegments.length - 1) { currentLevel = existingNode.childNodes; } }); }); // Log the final tree structure console.log(JSON.stringify(tree, null, 2));
How This Works
- Root Initialization: We start with an empty array (
tree) to hold our top-level nodes (path1, path2). - Path Splitting: Each path is split into segments (e.g.,
path1/subpath1/file1.docbecomes["path1", "subpath1", "file1.doc"]). - Node Creation/Traversal:
- For each segment, we check if a node with that
titlealready exists in the current level. - If not, we create a new node with the segment as
titleand an emptychildNodesarray, then add it to the current level. - We then move down into the
childNodesof the current node to process the next segment (unless we're at the last segment, which is a file with no children).
- For each segment, we check if a node with that
Output Explanation
The resulting tree array will contain two top-level nodes (path1 and path2), each with their respective child nodes matching your expected structure. If you need to wrap these in a single root node (e.g., with title: "Root"), you can do so with:
const wrappedTree = { title: "Root", childNodes: tree };
内容的提问来源于stack exchange,提问作者ganesh deshmukh

