我有一个文件对象,其中包含以下属性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只是例子。它将是实际的文件名,包括文件路径
答案 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());
...当然假设Source
和Target
属于string
类型。