在LINQ中排序和分组

Jon*_*ono 13 c# linq grouping

我有一个字符串元组列表,说(P1,P2)

我想知道是否有一个LINQ语句,我可以按P1(按升序)分组,并让该组包含该组的所有P2值(按降序排列).

输入:("A","B"),("A","C"),("D","B")我想得到两组:"A"和"D"(in该组"A"包含"C"和"B"(按此顺序,每次),组"D"包含"B".

这是否可以使用内置的LINQ类,还是我需要迭代组并自行排序?

Jon*_*eet 21

不,这并不难 - 您只需要跟踪您是否正在查看组内的组或元素.这是一个示例查询:

var query = from tuple in tuples
            orderby tuple.P1
            group tuple.P2 by tuple.P1 into g
            select new { Group = g.Key,
                         Elements = g.OrderByDescending(p2 => p2) };
Run Code Online (Sandbox Code Playgroud)

这是一个完整的示例(为了Tuple简单起见,如果您使用的是.NET 3.5,请避免使用.NET 4的类型):

using System;
using System.Collections.Generic;
using System.Linq;

public class MyTuple
{
    public string P1 { get; set; }
    public string P2 { get; set; }
}

class Test
{
    static void Main()
    {
        List<MyTuple> tuples = new List<MyTuple>
        {
            new MyTuple { P1 = "A", P2 = "B" },
            new MyTuple { P1 = "A", P2 = "C" },
            new MyTuple { P1 = "D", P2 = "B" },
        };

        var query = from tuple in tuples
            orderby tuple.P1
            group tuple.P2 by tuple.P1 into g
            select new { Group = g.Key,
                         Elements = g.OrderByDescending(p2 => p2) };

        foreach (var group in query)
        {
            Console.WriteLine("{0}:", group.Group);
            foreach (var value in group.Elements)
            {
                Console.WriteLine("  {0}", value);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您乐意按照"需要知道"的顺序进行排序,可能会稍微简单一点:

var query = from tuple in tuples
    orderby tuple.P1
    group tuple.P2 by tuple.P1;

foreach (var group in query)
{
    Console.WriteLine("{0}:", group.Key);
    foreach (var value in group.OrderByDescending(x => x))
    {
        Console.WriteLine("  {0}", value);
    }
}
Run Code Online (Sandbox Code Playgroud)


Lee*_*Lee 5

List<Tuple<string, string>> tuples = //
var grouped = tuples.GroupBy(t => t.First)
    .OrderBy(grp => grp.Key)
    .Select(grp => new { Key = grp.Key, Items = grp.OrderBy(t => t.Second) });
Run Code Online (Sandbox Code Playgroud)