跳转至

数据分组⚓︎

一、分组方法⚓︎

在查询语法中,通过 group...by 关键字完成对序列的分组,数据分到不同的组,使每组中的元素拥有公共的属性,比如:

var query = from number in numbers group number by number % 2;

在方法语法中,存在标准查询运算符方法来完成这一功能,下表列出了对数据进行分组的标准查询运算符方法:

方法 说明 查询语法 链接
GroupBy 对共享通用属性的元素进行分组,每组由一个 IGrouping<K,E> 对象表示 group...by Enumerable.GroupByQueryable.GroupBy
ToLookup 将元素插入基于键选择器函数的 Lookup<K,E>(一种一对多字典) × Enumerable.ToLookup

二、GroupBy⚓︎

GroupBy() 方法用来完成对数据分组,下列代码中显示了查询语法和方法语法对分组的完成:

List<int> numbers = new List<int>() { 35, 44, 200, 84, 3987, 4, 199, 329, 446, 208 };  

// 查询语法
IEnumerable<IGrouping<int, int>> query = from number in numbers  
                                         group number by number % 2;  

foreach (var group in query)  
{  
    Console.WriteLine(group.Key == 0 ? "\nEven numbers:" : "\nOdd numbers:");  
    foreach (int i in group)  
        Console.WriteLine(i);  
}

Console.WriteLine();

// 方法语法
IEnumerable<IGrouping<int, int>> query2 = numbers.GroupBy(number => numbers % 2);

foreach (var group in query2)
{
    Console.WriteLine(group.Key == 0 ? "\nEven numbers:" : "\nOdd numbers:");
    foreach (int i in group)
        Console.WriteLine(i);
}

/* This code produces the following output:  

    Odd numbers:
    35 3987 199 329
    Even numbers:
    44 200 84 4 446 208

    Odd numbers:
    35 3987 199 329
    Even numbers:
    44 200 84 4 446 208
*/

三、ToLookup⚓︎

ToLookup() 方法可以根据选择器函数返回一个 Lookup<TKey,TElement> 类型的数据。

class Package
{
    public string Company { get; set; }
    public double Weight { get; set; }
    public long TrackingNumber { get; set; }
}

public static void ToLookupEx1()
{
    // Create a list of Packages.
    List<Package> packages =
        new List<Package>
            { new Package { Company = "Coho Vineyard",
                  Weight = 25.2, TrackingNumber = 89453312L },
              new Package { Company = "Lucerne Publishing",
                  Weight = 18.7, TrackingNumber = 89112755L },
              new Package { Company = "Wingtip Toys",
                  Weight = 6.0, TrackingNumber = 299456122L },
              new Package { Company = "Contoso Pharmaceuticals",
                  Weight = 9.3, TrackingNumber = 670053128L },
              new Package { Company = "Wide World Importers",
                  Weight = 33.8, TrackingNumber = 4665518773L } };

    // Create a Lookup to organize the packages.
    // Use the first character of Company as the key value.
    // Select Company appended to TrackingNumber
    // as the element values of the Lookup.
    ILookup<char, string> lookup = packages
                .ToLookup(p => p.Company[0],
                        p => p.Company + " " + p.TrackingNumber);

    // Iterate through each IGrouping in the Lookup.
    foreach (IGrouping<char, string> packageGroup in lookup)
    {
        // Print the key value of the IGrouping.
        Console.WriteLine(packageGroup.Key);
        // Iterate through each value in the
        // IGrouping and print its value.
        foreach (string str in packageGroup)
            Console.WriteLine("    {0}", str);
    }
}

/*
 This code produces the following output:

 C
     Coho Vineyard 89453312
     Contoso Pharmaceuticals 670053128
 L
     Lucerne Publishing 89112755
 W
     Wingtip Toys 299456122
     Wide World Importers 4665518773
*/