C#实现非层级CSV数据转层级结构:第三方工作流数据处理
Alright, let's tackle this problem of converting those flat node paths into a proper hierarchical structure for your mini program. I've worked through similar workflow system parsing tasks before, so here's a practical, step-by-step solution with code you can adapt right away:
First, you'll need to read all your flat files and structure the data into a list where each entry includes the node path and its associated properties. For example:
// Sample structured flat data (adjust based on how you read your files) const flatWorkflowNodes = [ { path: 'Root', properties: { workflowId: 'root_001', status: 'active' } }, { path: 'Root-Node1', properties: { workflowId: 'node1_002', status: 'active', type: 'task' } }, { path: 'Root-Node1-Node1', properties: { workflowId: 'node1_003', status: 'pending', type: 'subtask' } }, { path: 'Root-Node1-Node2', properties: { workflowId: 'node1_004', status: 'active', type: 'subtask' } }, { path: 'Root-Node1-Node2-Node1', properties: { workflowId: 'node1_005', status: 'pending', type: 'action' } }, { path: 'Root-Node2', properties: { workflowId: 'node2_006', status: 'active', type: 'task' } } ];
The core logic is to iterate through each path, split it into individual node segments, and build out the tree by either reusing existing nodes or creating new ones. We'll use a Map to cache nodes to avoid duplicates, and handle cases where nodes might share the same name under different parents (a common edge case).
Here's the implementation:
function buildWorkflowHierarchy(flatNodes) { const nodeCache = new Map(); let rootNode = null; flatNodes.forEach(nodeEntry => { const pathSegments = nodeEntry.path.split('-'); let currentParent = null; pathSegments.forEach((segment, index) => { // Create a unique key using the full path up to this segment to avoid name collisions const fullSegmentPath = pathSegments.slice(0, index + 1).join('-'); if (!nodeCache.has(fullSegmentPath)) { // Create new node const newNode = { name: segment, fullPath: fullSegmentPath, properties: index === pathSegments.length - 1 ? nodeEntry.properties : {}, children: [] }; nodeCache.set(fullSegmentPath, newNode); // Set root if this is the first segment if (index === 0) { rootNode = newNode; } else { // Attach to parent node's children array currentParent.children.push(newNode); } } // Update current parent to the current node for the next iteration currentParent = nodeCache.get(fullSegmentPath); }); }); return rootNode; } // Generate the hierarchy const workflowTree = buildWorkflowHierarchy(flatWorkflowNodes); // Log to verify (you can use this in your mini program's logic) console.log(JSON.stringify(workflowTree, null, 2));
- File Reading: In your mini program, you'll need to read all the flat files first. Depending on your storage setup (local files, cloud storage, etc.), use the corresponding API (like
wx.getFileSystemManager()for local files) to fetch each file's content and map it to theflatWorkflowNodesstructure above. - Property Handling: If properties are stored in separate files, make sure to match each property set to its corresponding node path before passing to the
buildWorkflowHierarchyfunction. - 后续处理: Once you have the hierarchical tree, you can use it for rendering tree UI components, running workflow validations, or any other processing your project requires. Most mini program UI frameworks (like Taro, or native WeChat Mini Program components) accept tree-structured data directly for tree views.
- Duplicate Paths: If your flat files might have duplicate paths, add a check to either merge properties or overwrite them based on your business needs.
- Performance: For large datasets, the
Maplookup ensures O(1) access time, so the overall process stays efficient even with hundreds of nodes.
内容的提问来源于stack exchange,提问作者Nick

