【IT168技术文档】
除了上述基本查询工具之外,许多操作符也提供了操作序列和编写查询的有用方法,从而在标准查询操作符的方便架构中为用户提供对结果的高级控制。
排序和分组
一般而言,对查询表达式的计算会导致以某种顺序生成一系列值,该顺序是底层信息源的固有顺序。要使开发人员能够显式控制这些值的生成顺序,应定义标准查询操作符来控制该顺序。这些操作符中最基本的就是 OrderBy 操作符。
OrderBy 和 OrderByDescending 操作符可应用于任何信息源,并允许用户提供可生成用于排序结果的值的键值提取函数。 OrderBy 和 OrderByDescending 还接受可用于对键施加部分顺序的可选比较函数。下面我们来看一个基本示例:
前两个查询表达式会生成根据字符串比较排序源成员的新序列。后两个查询会生成根据每个字符串的长度排序源成员的新序列。string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" }; // unity sort var s1 = names.OrderBy(s => s); var s2 = names.OrderByDescending(s => s); // sort by length var s3 = names.OrderBy(s => s.Length); var s4 = names.OrderByDescending(s => s.Length);
要允许多个排序准则,OrderBy 和 OrderByDescending 都应该返回 SortedSequence,而不是通用的 IEnumerable。两个操作符仅在 SortedSequence 上定义,分别名为 ThenBy 和 ThenByDescending,它们将应用附加(从属)的排序准则。 ThenBy/ThenByDescending 自身会返回 SortedSequence,以允许应用任何数量的 ThenBy/ThenByDescending 操作符:
在本例中,计算由 s1 引用的查询将生成以下值序列:string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" }; var s1 = names.OrderBy(s => s.Length).ThenBy(s => s);
除了 OrderBy 系列的操作符,标准查询操作符还包括 Reverse 操作符。Reverse 只枚举序列并以相反的顺序生成相同的值。与 OrderBy 不同,Reverse 在决定顺序时不考虑实际值本身,而仅仅依赖于底层源生成的值的顺序。"Burke", "David", "Frank", "Albert", "Connor", "George", "Harris", "Everett"
OrderBy 操作符可对值序列施加排序顺序。标准查询操作符还包括 GroupBy 操作符,该操作符可根据键值提取函数对值序列进行分区。GroupBy 操作符会返回一列 Grouping 值,其中每一个对应于所遇到的不同的键值。每个 Grouping 都包含键,以及映射到该键的值集合。Grouping 的公共协定如下所示:
最简单的 GroupBy 应用程序如下所示:public sealed class Grouping { public Grouping(K key, IEnumerable group); public Grouping(); public K Key { get; set; } public IEnumerable Group { set; get; } }
运行后,该程序会显示出以下结果:string[] names = { "Albert", "Burke", "Connor", "David", "Everett", "Frank", "George", "Harris"}; // group by length var grouping = names.GroupBy(s => s.Length); foreach (Grouping group in grouping) { Console.WriteLine("Strings of length {0}", group.Key); foreach (string value in group.Group) Console.WriteLine(" {0}", value); }
Strings of length 6 Albert Connor George Harris Strings of length 5 Burke David Frank Strings of length 7 Everett