OrderBy/ThenBy循环-C#中的嵌套列表
本文关键字:嵌套 列表 -C# ThenBy 循环 OrderBy | 更新日期: 2023-09-27 18:21:34
我有一个嵌套列表,
List<List<String>> 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 <= 3; i++)
{
tmp = tmp.ThenBy(x => 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<List<string>>
{
public int Compare(List<string> x, List<string> 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());