将.Net中的列表排序为一个字段,然后排序另一个字段

时间:2011-02-25 15:41:56

标签: c# linq sorting

我有一些对象列表,我需要根据它们的一些属性进行排序。这适用于按一个字段对其进行排序:

reportDataRows.Sort((x, y) => x["Comment1"].CompareTo(y["Comment1"]));
foreach (var row in reportDataRows) {
   ...
}

我在这里看到很多例子只用一个字段来做这件事。但是,我如何按一个字段排序,然后另一个字段?或者许多字段列表如何?似乎使用LINQ orderby然后将是最好的,但我不知道如何使用它。

对于参数,这样的东西支持任意数量的字段进行排序会很好:

var sortBy = new List<string>(){"Comment1","Time"};

我不想在我的每个应用程序中编写代码来执行此操作。我计划将此排序代码移动到保存数据的类,以便它可以执行更高级的操作,例如使用参数列表并隐式识别该字段是日期并将其排序为日期而不是字符串。 reportDataRow对象包含具有此信息的字段,因此我不必进行任何混乱的检查以确定该字段是否应该是日期。

7 个答案:

答案 0 :(得分:7)

是的,我认为使用OrderByThenBy更有意义:

foreach (var row in reportDataRows.OrderBy(x => x["Comment1"]).ThenBy(x => x["Comment2"]) 
{
    ...
}

这假设你要订购的另一件事是“Comment2”。

答案 1 :(得分:2)

试试这个:

reportDataRows.Sort((x, y) =>
{
    var compare = x["Comment1"].CompareTo(y["Comment1"]);
    if(compare != 0)
        return compare;

    return x["Comment2"].CompareTo(y["Comment2"]);
});

答案 2 :(得分:1)

查看msdn。上的ThenBy示例。

答案 3 :(得分:1)

您可能希望查看this previous answer我在哪里发布了一个扩展方法,该方法在LINQ中处理多个顺序。这允许这种语法:

myList.OrderByMany(x => x.Field1, x => x.Field2);

答案 4 :(得分:0)

如果您要比较自己的对象,则可以实现IComparable界面 否则,您可以使用IComparer界面。

答案 5 :(得分:0)

你明白了。 Enumerable.OrderBy()。ThenBy()是你的票。它的外观与它看起来完全一样;元素按每个投影排序,通过比较下一个投影来确定关系。您可以根据需要链接任意数量的ThenBys,还有OrderByDesc和ThenByDesc方法,它们将按降序对该投影进行排序。

正如Albin指出的那样,除非您将排序结果分配回原始变量,否则OrderBy链不会触及原始列表,如下所示:

reportDataRows = reportDataRows.OrderBy(x=>x.Comment1).ThenBy(x=>x.Comment2).ToList();

通常,OrderBy的执行速度会比List.Sort()略慢;该算法设计用于任何IEnumerable系列元素,因此为了排序(这需要知道系列的每个元素),它将其整个源可以枚举成一个新数组。但是,OrderBy具有明显优于Sort的优势,因为它是一种“稳定”的类型;彼此完全相等的元素将在排序的可枚举中保留它们的“相对顺序”(在遍历未排序列表时遇到的两个中的第一个将是迭代排序列表时遇到的两个中的第一个)。

答案 6 :(得分:0)

使用LINQ方法语法:

var sortedRows = reportDataRows.OrderBy(r => r["Comment1"])
                   .ThenBy(r => r["AnotherField"];

foreach (var row in sortedRows) {
   ...
}

使用查询理解语法更具可读性:

var sortedRows = from r in reportDataRows
                 orderby r["Comment1"], r["Comment2"]
                 select r;
foreach (var row in sortedRows) {
   ...
}