OrderBy / ThenBy循环 – C#中的嵌套列表
我有一个嵌套列表,
List<List> intable;
我想在哪里排序所有列。 问题是列数取决于用户输入。
像这样排序列表工作正常(假设此示例为4列)
var tmp = intable.OrderBy(x => x[0]); tmp = tmp.ThenBy(x => x[1]); tmp = tmp.ThenBy(x => x[2]); tmp = tmp.ThenBy(x => x[3]); intable = tmp.ToList();
但是,当我把它放在循环中时,像这样:
var tmp = intable.OrderBy(x => x[0]); for (int i = 1; i x[i]); } intable = tmp.ToList();
它不再正常工作,只排序第四列。
这是访问修改后的闭包的情况 。 将代码更改为此,它将起作用:
var tmp = intable.OrderBy(x => x[0]); for (int i = 1; i <= 3; i++) { var thisI = i; tmp = tmp.ThenBy(x => x[thisI]); } intable = tmp.ToList();
Eric Lippert撰写了一篇由两部分组成的文章,描述了这个问题。 它无法按预期工作的原因 – 简而言之 – 因为当您调用ToList()
时,LINQ仅在使用i
的最后一个值时进行评估。 这跟你写的一样:
var tmp = intable.OrderBy(x => x[0]); tmp = tmp.ThenBy(x => x[3]); tmp = tmp.ThenBy(x => x[3]); tmp = tmp.ThenBy(x => x[3]); intable = tmp.ToList();
创建一个比较器
class StringListComparer : IComparer> { public int Compare(List x, List y) { int minLength = Math.Min(x.Count, y.Count); for (int i = 0; i < minLength; i++) { int comp = x[i].CompareTo(y[i]); if (comp != 0) { return comp; } } return x.Count.CompareTo(y.Count); } }
然后像这样对列表进行排序
intable.Sort(new StringListComparer());