在集合中查找根URL和子网URL

时间:2018-04-19 19:26:50

标签: c#

我有一个强大的类型列表字符串集合,有时会在域级别表示根级别站点,但有时不会。例如:

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

1 个答案:

答案 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