如何在C#中使用LINQ进行两级排序

本文关键字:排序 两级 LINQ | 更新日期: 2023-09-27 18:05:07

我有一个List<string>对象,看起来像这样:

option 1
 line a
 line b
 line c
option 3
 line x
 line z
 line y
option 2
 a1
 a4
 a2
 a3

所有次要细节缩进一个空格。是否可以使用LINQ对该列表进行排序?我只知道最基本的订购和当试图对第一列中有空格的字符串的辅助行进行排序时,我真的不知道从哪里开始。

以下是我希望排序后列表的样子

option 1
 line a
 line b
 line c
option 2
 a1
 a2
 a3
 a4
option 3
 line x
 line y
 line z

我刚刚更新了这个问题。我有List<string>,但出版时就被砍掉了。

如何在C#中使用LINQ进行两级排序

使用:

yourEnumerable.OrderBy(y => y.Key).ThenBy(y => y.Prop2)

请参阅MSDN上的文档:http://msdn.microsoft.com/en-us/library/bb534966.aspx和http://msdn.microsoft.com/en-us/library/bb534743.aspx

更新:尝试下面的代码进行解析和排序,它有点伪:

string lineRead;
string current;
var dictionary = new Dictionary<string, List<string>>);
while((lineRead = reader.ReadLine())
{
    if(!lineRead.StartsWith("  "))
    {
        dictionary.Add(lineRead, new List<string>());
        current = lineRead;
    }
    else
    {
        dictionary[current].Add(lineRead);
    }
}
dictionary.Keys.ToList().ForEach(y => dictionary[y] = dictionary[y].OrderBy(x => x).ToList());
dictionary.OrderBy(y => y.Key);

虽然没有内置的方法,但LINQ提供了一个简单而优雅的答案:

    static IEnumerable<string> Sort(IEnumerable<string> unsorted)
    {
        string option = null;
        return
            from line in unsorted
            let isSubitem = line.StartsWith(" ")
            let parent = isSubitem ? option : option = line
            orderby parent, isSubitem, line
            select line;
    }

关键是能够将子项(以空格开头的行(与其父选项(开头没有空格的行(相关联。我们首先声明一个局部变量option,它将始终包含当前父选项。

在LINQ表达式中,要做的第一件事是告诉它迭代unsorted输入中的项,为每个字符串指定名称line。然后我们确定它是否是一个子项,并将结果放入isSubItem中。

现在关键来了——将父选项放入parent中。如果该行是子项,则它只使用存储的option。如果不是,option = line部分将当前行存储为option将其分配给parent

然后,这只是一个简单的排序问题,首先按父选项排序,然后按行是否为父项排序(以确保父项始终显示在其子项之前(,然后按子项排序。

如果您想使用较短的基于lambda的语法,并且不希望额外名称的可读性,那么只需几行即可完成:

    static IEnumerable<string> Sort(IEnumerable<string> unsorted)
    {
        string option = null;
        return
            unsorted
            .OrderBy(line => line.StartsWith(" ") ? option : option = line)
            .ThenBy(line => line.StartsWith(" ") ? line : null);
    }

类似于:

                    .OrderBy(x => x.option)
                    .ThenBy(x=>x.secondary)
list.OrderBy(<a delegate that will sort your array>).ThenBy(<a delegate that will sort your array again>)

你就是这么认为的吗?

好吧,我根据你的问题回答了这个问题,这就是代理的方式,你的第一个代理基本上会将项目分组到每个选项下,然后对其进行排序,下一个代理会对选项标签下的每个项目进行排序。。

另一种方法是将其存储在字典中:如下所示:键值(列表(选项1 a1、a2等选项2 as1、as2等等

然后您将对值和键进行排序,然后如果您想将其放入列表中(如果需要(,则仅