如何高效统计文本文件中各文件夹的直接子项数量?
问题描述
我有一个存储文件夹路径的文本文件,内容示例如下:
Folder1 Folder1/SubFolder1 Folder1/SubFolder1/SubSubFolder1 Folder1/SubFolder1/SubSubFolder2 Folder1/SubFolder1/SubSubFolder3 Folder1/SubFolder1/SubSubFolder4 Folder1/SubFolder2 Folder1/SubFolder2/SubSubFolder1 Folder1/SubFolder2/SubSubFolder2 Folder1/SubFolder2/SubSubFolder3 Folder1/SubFolder2/SubSubFolder4 Folder1/SubFolder2/SubSubFolder5 Folder1/SubFolder2/SubSubFolder6 Folder1/SubFolder2/SubSubFolder6/SubSubSubFolder1 Folder1/SubFolder3 Folder2 Folder2/SubFolder1 Folder2/SubFolder1/SubSubFolder1 Folder2/SubFolder1/SubSubFolder2 Folder2/SubFolder1/SubSubFolder3 Folder2/SubFolder1/SubSubFolder4 Folder2/SubFolder2 Folder2/SubFolder2/SubSubFolder1 Folder2/SubFolder2/SubSubFolder2 Folder2/SubFolder2/SubSubFolder3 Folder2/SubFolder2/SubSubFolder4 Folder2/SubFolder2/SubSubFolder5 Folder2/SubFolder2/SubSubFolder6 Folder2/SubFolder2/SubSubFolder7 Folder2/SubFolder2/SubSubFolder6/SubSubFolder1 Folder2/SubFolder3 Folder2/SubFolder4
需要生成一个<string, int>类型的字典,记录每个文件夹名称及其直接子项(仅顶层)的数量,示例输出如下:
Folder1, 3 // SubFolder1, SubFolder2, SubFolder3 Folder1/SubFolder1,4 // SubSubFolder1, SubSubFolder2, SubSubFolder3, SubSubFolder4 Folder1/SubFolder2,6 //SubSubFolder1, SubSubFolder2, SubSubFolder3, SubSubFolder4, SubSubFolder5, SubSubFolder6 Folder1/SubFolder2/SubSubFolder6,1 //SubSubSubFolder1 Folder1/SubFolder3,0 Folder2,4 // SubFolder1, SubFolder2, SubFolder3, SubFolder4 Folder2/SubFolder1,4 // SubSubFolder1, SubSubFolder2, SubSubFolder3, SubSubFolder4 Folder2/SubFolder2,7 // SubSubFolder1, SubSubFolder2, SubSubFolder3, SubSubFolder4, SubSubFolder5, SubSubFolder6, SubSubFolder7 Folder2/SubFolder2/SubSubFolder6,1 //SubSubSubFolder1 Folder2/SubFolder3,0 Folder2/SubFolder4,0
目前我能通过遍历所有行实现,但方法复杂繁琐,现有代码片段如下:
var allLines = File.ReadAllLines(filePath); foreach (var line in allLines) { var subFolderCount = 0; var subFolderPath = Path.Combine(folderPath, line); //... }
请问是否有更简便高效的实现方式?
高效实现方案
可以利用LINQ分组统计+字典初始化的方式简化逻辑,核心思路是先统计每个父路径的直接子项数量,再将所有原始路径纳入字典,无直接子项的路径计数设为0。具体代码如下:
var allLines = File.ReadAllLines(filePath); // 第一步:统计每个父路径对应的直接子项数量 var parentChildCounts = allLines .Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains('/')) .Select(line => line.Substring(0, line.LastIndexOf('/'))) // 提取当前路径的父路径 .GroupBy(parentPath => parentPath) .ToDictionary(group => group.Key, group => group.Count()); // 第二步:生成包含所有路径的最终字典,无直接子项的路径计数为0 var folderChildCounts = allLines .Distinct() // 处理文本中可能存在的重复路径 .ToDictionary( folderPath => folderPath, folderPath => parentChildCounts.TryGetValue(folderPath, out var count) ? count : 0 ); // 可选:打印结果验证 foreach (var kvp in folderChildCounts) { Console.WriteLine($"{kvp.Key}, {kvp.Value}"); }
逻辑说明
- 第一部分通过LINQ筛选出有父路径的项,提取父路径后分组统计,快速得到每个父路径对应的直接子项数量
- 第二部分将所有原始路径转为字典,对于每个路径,从统计结果中获取子项数量,不存在则设为0
- 该方式避免了嵌套遍历,时间复杂度为O(n),比逐行判断的逻辑更简洁高效
内容的提问来源于stack exchange,提问作者Pankaj
相关产品推荐
相关产品推荐

