在字符串集合中识别根URL与子站点URL并转换为层级对象
解决URL转树形UrlObject集合的方案
我来帮你搞定这个需求!咱们的目标是把一堆平级的URL字符串,转换成嵌套的UrlObject树形结构——每个节点包含自身URL,以及子路径对应的UrlObject列表。下面是具体的实现思路和代码:
核心思路
要构建树形结构,关键是找到每个URL的父节点:
- 比如
http://x.com/y的父节点是http://x.com http://a.com/b/c/d的父节点是http://a.com/b/c- 如果某个URL的父URL不在原集合里(比如示例中的
http://a.com/b/c),它就作为根节点存在
具体步骤:
- 把所有URL转换成
UrlObject实例,用字典存储方便快速查找 - 按URL的路径长度排序,先处理短路径(确保父节点先被创建)
- 遍历每个URL,找到对应的父节点,把当前节点挂到父节点的
subUrls中;找不到父节点就作为根节点
代码实现
首先是你定义的UrlObject类(我给SubUrls加了初始化,避免空引用):
public class UrlObject { public string Url { get; set; } public List<UrlObject> SubUrls { get; set; } = new List<UrlObject>(); }
然后是核心转换方法:
public static List<UrlObject> ConvertToUrlTree(List<string> urls) { // 用字典存储URL和对应UrlObject,保证O(1)的查找效率 var urlObjectMap = new Dictionary<string, UrlObject>(); foreach (var url in urls) { urlObjectMap[url] = new UrlObject { Url = url }; } // 按路径长度排序,先处理根级/短路径URL,确保父节点先被创建 var sortedUrls = urls.OrderBy(url => new Uri(url).Segments.Length).ToList(); var rootNodes = new List<UrlObject>(); foreach (var url in sortedUrls) { var currentNode = urlObjectMap[url]; var uri = new Uri(url); // 如果是最顶层根域(比如http://x.com,Segments只有["/"]),直接加入根节点列表 if (uri.Segments.Length == 1) { rootNodes.Add(currentNode); continue; } // 拼接父URL:去掉最后一个路径段 var parentSegments = uri.Segments.Take(uri.Segments.Length - 1).ToArray(); var parentUriBuilder = new UriBuilder(uri) { Path = string.Concat(parentSegments).TrimEnd('/') }; var parentUrl = parentUriBuilder.Uri.ToString(); // 找到父节点就把当前节点挂上去,找不到就作为根节点处理 if (urlObjectMap.TryGetValue(parentUrl, out var parentNode)) { parentNode.SubUrls.Add(currentNode); } else { rootNodes.Add(currentNode); } } return rootNodes; }
测试示例
用你给出的URL列表测试:
var inputUrls = new List<string> { "http://x.com", "http://x.com/y", "http://x.com/y/w", "http://x.com/y/z", "http://a.com/b/c", "http://a.com/b/c/d", "http://a.com/b/c/e" }; var urlTree = ConvertToUrlTree(inputUrls);
最终得到的树形结构:
- 根节点1:
http://x.com- 子节点:
http://x.com/y- 子节点:
http://x.com/y/w - 子节点:
http://x.com/y/z
- 子节点:
- 子节点:
- 根节点2:
http://a.com/b/c- 子节点:
http://a.com/b/c/d - 子节点:
http://a.com/b/c/e
- 子节点:
注意事项
- 用
Uri类解析URL比手动拆分字符串更可靠,能处理各种URL格式(比如带/不带末尾斜杠的情况) - 提前初始化
SubUrls为空列表,避免后续添加子节点时出现空引用异常 - 如果原集合中某个URL的父URL不存在,它会自动成为根节点,完全符合你的示例场景
内容的提问来源于stack exchange,提问作者user3010406
相关产品推荐
相关产品推荐

