在C#中将“链”链接在一起

时间:2017-01-07 07:49:42

标签: c# linq list sorting

我有一个文件对象,其中包含以下属性C#

File {
    Source;
    Target;
}

我有一个文件列表,如下所示:

File[0]- Source :B :Target :C
File[1]- Source :A :Target :B
File[2]- Source :AA :Target :E
File[3]- Source :F :Target :G
File[4]- Source :G :Target :H
File[5]- Source :E :Target :F
File[6]- Source :C :Target :AA

如何对其进行排序以使下一项的来源等于上一项的目标?

File[0]- Source :A :Target :B
File[1]- Source :B :Target :C
File[2]- Source :C :Target :AA
File[3]- Source :AA :Target :E
File[4]- Source :E :Target :F
File[5]- Source :F :Target :G
File[6]- Source :G :Target :H

A,B ....来源中给出的H只是例子。它将是实际的文件名,包括文件路径

1 个答案:

答案 0 :(得分:4)

给出一个文件列表:

List<File> files;

简单地说:

var sorted = files.OrderBy(f => f.Source).ToList();

在回答编辑过的问题时,这是一种可行的方法。让我们定义一个通用方法:

public static IEnumerable<T> Chain<T, S> (
    IEnumerable<T> list, Func<T, S> sourceSelector, Func<T, S> targetSelector, T seed) {
    var dict = list.ToDictionary(sourceSelector, x => x);
    var curr = seed; 

    do {
        yield return curr; 
    } while(dict.TryGetValue(targetSelector(curr), out curr));
}

我在这里使用字典来获取大型列表的速度,因为字典查找是O(1)。但是,人们可以很容易地使用简单的线性搜索,其分摊的查找时间为O(n),但对于小型列表的开销较小。

可以使用以下方法:

var list = new List<Tuple<int, int>> {
    Tuple.Create(1, 2),
    Tuple.Create(3, 5),
    Tuple.Create(2, 3),
    Tuple.Create(8, 13),
    Tuple.Create(5, 8),
};

var chained = Chain<Tuple<int, int>, int>(list,
    x => x.Item1,
    x => x.Item2,
    list.First());

foreach (var i in chained)
    Console.Write(i); 

打印出来:

(1, 2)(2, 3)(3, 5)(5, 8)(8, 13)

在您的情况下,您可以写:

var chained = Chain<File, string>(files,
    f => f.Source,
    f => f.Target,
    files.OrderBy(f => f.Source).First());

...当然假设SourceTarget属于string类型。