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();

它不再正常工作,只对第四列进行排序。

OrderBy/ThenBy循环-C#中的嵌套列表

这是访问修改后的闭包的情况。将代码更改为这样,它就会工作:

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());