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

时间:2011-08-11 12:44:25

标签: c#

我有一个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对此列表进行排序?我只知道非常基本的排序和 在尝试对第一列中包含空格的字符串的辅助行进行排序时,真的不知道从哪里开始。

以下是我希望List在排序后的样子

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

我刚刚更新了这个问题。我有List<string>但是在发布时它被砍掉了。

4 个答案:

答案 0 :(得分:5)

使用:

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

请参阅MSDN上的文档:http://msdn.microsoft.com/en-us/library/bb534966.aspxhttp://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);

答案 1 :(得分:2)

虽然没有内置方法可以做到这一点,但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

然后它只是一个简单的排序问题,首先是父选项,然后是一行是否为父(确保父总是在其子项之前显示),然后是子-items。

如果你想使用较短的基于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);
    }

答案 2 :(得分:0)

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

你知道什么?

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

另一种方法是将其存储在字典中:如下所示: 关键价值(清单) option1 a1,a2等 option2 as1,as2等 等

然后你将对值和键进行排序,然后如果你想将它放入一个列表中,只需要

答案 3 :(得分:0)

类似的东西:

                    .OrderBy(x => x.option)
                    .ThenBy(x=>x.secondary)