我有一个嵌套列表,
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();
它不再正常工作,只对第四列进行排序。
答案 0 :(得分:25)
这是访问修改后的闭包的情况。将代码更改为此代码,它将起作用:
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编写了two-part article来描述这个问题。它无法按预期工作的原因 - 简而言之 - 因为当您调用i
时,LINQ仅在使用ToList()
的最后一个值时进行评估。这和你写的一样:
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();
答案 1 :(得分:0)
创建比较器
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());