我有一个强大的类型列表字符串集合,有时会在域级别表示根级别站点,但有时不会。例如:
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
我需要将字符串集合转换为强类型自定义对象的集合,如下所示:
public class UrlObject
{
public string url { get; set; }
public List<UrlObject> subUrls { get; set; }
}
&#34; Parent&#34;中的字符数和斜杠数量。网址可能会有所不同,我很好奇是否有办法建立一个允许灵活调整&#34;父母&#34;的大小的集合。
此方法的预期输出将是具有两个对象的列表集合,如下所示:
对象1
Parent - http://x.com
subUrls- http://x.com/y,
http://x.com/y/w,
http://x.com/y/z
对象2
Parent: http://a.com/b/c
subUrls-http://a.com/b/c/d,
http://a.com/b/c/e
答案 0 :(得分:2)
.NET中已经存在一个类,可以让您的生活更轻松:System.Uri
。您可以创建一个“conatiner”类,而不是您的自定义类:
public class UriContainer
{
public Uri Parent { get; set; }
public List<Uri> Children { get; set; }
}
您可以使用一点LINQ轻松地将字符串网址集合转换为Uri
个对象:
var urlStringList = 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"
};
IEnumerable<Uri> uris = urlStringList.Select(x => new Uri(x));
从那里你可以GroupBy()
Host
属性,然后在每个组内,OrderBy()
Segments.Length
属性。然后取First()
一个(根据你的例子,这是具有最少段的那个,也就是“父”),然后你把其余的作为“孩子”:
var containerList = new List<UriContainer>();
foreach(var groupedUri in uris.GroupBy(x => x.Host))
{
var sorted = groupedUri.OrderBy(x => x.Segments.Length);
containerList.Add(new UriContainer()
{
Parent = sorted.First(),
Children = sorted.Skip(1).ToList()
});
}
上面的代码会给你一个这样的结构:
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
----------------------
此代码的错误预防非常少,您可能希望确保项目不为空等等,但它至少为您提供了一个起点。
小提琴here