zoukankan      html  css  js  c++  java
  • LINQ操作符四:排序操作符

    Linq中的排序操作符包括OrderBy、OrderByDescending、ThenBy、ThenByDescending和Reverse,提供了升序或者降序排序。

    一、OrderBy操作符

    OrderBy操作符用于对输入序列中的元素进行排序,排序基于一个委托方法的返回值顺序。排序过程完成后,会返回一个类型为IOrderEnumerable<T>的集合对象。其中IOrderEnumerable<T>接口继承自IEnumerable<T>接口。下面来看看OrderBy的定义:

    从上面的截图中可以看出,OrderBy是一个扩展方法,只要实现了IEnumerable<T>接口的就可以使用OrderBy进行排序。OrderBy共有两个重载方法:第一个重载的参数是一个委托类型和一个实现了IComparer<T>接口的类型。第二个重载的参数是一个委托类型。看看下面的示例:

    定义产品类:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     public class Products
    10     {
    11         public int Id { get; set; }
    12         public int CategoryId { get; set; }
    13         public string Name { get; set; }
    14         public double Price { get; set; }
    15         public DateTime CreateTime { get; set; }
    16     }
    17 }

    在Main()方法里面调用:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             // 初始化数据
    14             List<Products> listProduct = new List<Products>()
    15             {
    16                new Products(){Id=1,CategoryId=1, Name="C#高级编程第10版", Price=100.67,CreateTime=DateTime.Now},
    17                new Products(){Id=2,CategoryId=1, Name="Redis开发和运维", Price=69.9,CreateTime=DateTime.Now.AddDays(-19)},
    18                new Products(){Id=3,CategoryId=1, Name="ASP.NET Core", Price=57,CreateTime=DateTime.Now.AddMonths(-3)},
    19                new Products(){Id=4,CategoryId=1, Name="Entity Framework 6.x", Price=97,CreateTime=DateTime.Now.AddMonths(-1)}
    20             };
    21             Console.WriteLine("方法语法");
    22             // 1、查询方法,返回匿名类
    23             var list = listProduct.OrderBy(p => p.CreateTime).Select(p => new { id = p.Id, ProductName = p.Name,ProductPrice=p.Price,PublishTime=p.CreateTime }).ToList();
    24             foreach (var item in list)
    25             {
    26                 Console.WriteLine($"item:{item}");
    27             }
    28             Console.WriteLine("查询表达式");
    29             // 2、查询表达式,返回匿名类
    30             var listExpress = from p in listProduct orderby p.CreateTime select new { id = p.Id, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime };
    31             foreach (var item in listExpress)
    32             {
    33                 Console.WriteLine($"item:{item}");
    34             }
    35 
    36             Console.ReadKey();
    37         }
    38     }
    39 }

    结果:

    从截图中可以看出,集合按照CreateTime进行升序排序。

    在来看看第一个重载方法的实现:

    先定义PriceComparer类实现IComparer<T>接口,PriceComparer类定义如下:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     public class PriceComparer : IComparer<double>
    10     {
    11         public int Compare(double x, double y)
    12         {
    13             if (x > y)
    14             {
    15                 return 1;     //表示x>y
    16             }
    17             else if (x < y)
    18             {
    19                 return -1;    //表示x<y
    20             }
    21             else
    22             {
    23                 return 0;     //表示x=y
    24             }
    25         }
    26     }
    27 }

    在Main()方法里面调用:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             // 初始化数据
    14             List<Products> listProduct = new List<Products>()
    15             {
    16                new Products(){Id=1,CategoryId=1, Name="C#高级编程第10版", Price=100.67,CreateTime=DateTime.Now},
    17                new Products(){Id=2,CategoryId=1, Name="Redis开发和运维", Price=69.9,CreateTime=DateTime.Now.AddDays(-19)},
    18                new Products(){Id=3,CategoryId=1, Name="ASP.NET Core", Price=57,CreateTime=DateTime.Now.AddMonths(-3)},
    19                new Products(){Id=4,CategoryId=1, Name="Entity Framework 6.x", Price=97,CreateTime=DateTime.Now.AddMonths(-1)}
    20             };
    21             Console.WriteLine("方法语法");
    22             // 1、查询方法,按照价格升序排序,返回匿名类
    23             var list = listProduct.OrderBy(p => p.Price,new PriceComparer()).Select(p => new { id = p.Id, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime }).ToList();
    24             foreach (var item in list)
    25             {
    26                 Console.WriteLine($"item:{item}");
    27             }
    28             Console.ReadKey();
    29         }
    30     }
    31 }

    结果:

    注意:orderby必须在select之前出现,查询表达式最后只可能出现select或者groupby。

    二、OrderByDescending

    OrderByDescending操作符的功能与OrderBy操作符基本相同,二者只是排序的方式不同。OrderBy是升序排序,而OrderByDescending则是降序排列。下面看看OrderByDescending的定义:
    从方法定义中可以看出,OrderByDescending的方法重载和OrderBy的方法重载一致。来看下面的例子:
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             // 初始化数据
    14             List<Products> listProduct = new List<Products>()
    15             {
    16                new Products(){Id=1,CategoryId=1, Name="C#高级编程第10版", Price=100.67,CreateTime=DateTime.Now},
    17                new Products(){Id=2,CategoryId=1, Name="Redis开发和运维", Price=69.9,CreateTime=DateTime.Now.AddDays(-19)},
    18                new Products(){Id=3,CategoryId=1, Name="ASP.NET Core", Price=57,CreateTime=DateTime.Now.AddMonths(-3)},
    19                new Products(){Id=4,CategoryId=1, Name="Entity Framework 6.x", Price=97,CreateTime=DateTime.Now.AddMonths(-1)}
    20             };
    21             // 注意:OrderByDescending的方法语法和查询表达式写法有些不同。
    22             Console.WriteLine("方法语法");
    23             // 1、查询方法,按照时间降序排序,返回匿名类
    24             var list = listProduct.OrderByDescending(p => p.CreateTime).Select(p => new { id = p.Id, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime }).ToList();
    25             foreach (var item in list)
    26             {
    27                 Console.WriteLine($"item:{item}");
    28             }
    29             Console.WriteLine("查询表达式");
    30             var listExpress = from p in listProduct orderby p.CreateTime descending select new { id = p.Id, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime };
    31             foreach (var item in list)
    32             {
    33                 Console.WriteLine($"item:{item}");
    34             }
    35             Console.ReadKey();
    36         }
    37     }
    38 }

     结果:

    从截图中可以看出:输出结果按照时间降序排序。在来看看另外一个重载方法的调用:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             // 初始化数据
    14             List<Products> listProduct = new List<Products>()
    15             {
    16                new Products(){Id=1,CategoryId=1, Name="C#高级编程第10版", Price=100.67,CreateTime=DateTime.Now},
    17                new Products(){Id=2,CategoryId=1, Name="Redis开发和运维", Price=69.9,CreateTime=DateTime.Now.AddDays(-19)},
    18                new Products(){Id=3,CategoryId=1, Name="ASP.NET Core", Price=57,CreateTime=DateTime.Now.AddMonths(-3)},
    19                new Products(){Id=4,CategoryId=1, Name="Entity Framework 6.x", Price=97,CreateTime=DateTime.Now.AddMonths(-1)}
    20             };
    21             Console.WriteLine("方法语法");
    22             // 1、查询方法,按照价格降序排序,返回匿名类
    23             var list = listProduct.OrderByDescending(p => p.Price, new PriceComparer()).Select(p => new { id = p.Id, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime }).ToList();
    24             foreach (var item in list)
    25             {
    26                 Console.WriteLine($"item:{item}");
    27             }
    28             Console.ReadKey();
    29         }
    30     }
    31 }

    结果:

    输出结果也是按照时间降序排序。

    三、ThenBy排序

    ThenBy操作符可以对一个类型为IOrderedEnumerable<T>,(OrderBy和OrderByDesceding操作符的返回值类型)的序列再次按照特定的条件顺序排序。ThenBy操作符实现按照次关键字对序列进行升序排列。下面来看看ThenBy的定义:

    从截图中可以看出:ThenBy()方法扩展的是IOrderedEnumerable<T>,因此ThenBy操作符长常常跟在OrderBy和OrderByDesceding之后。看下面的示例:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             // 初始化数据
    14             List<Products> listProduct = new List<Products>()
    15             {
    16                new Products(){Id=1,CategoryId=1, Name="C#高级编程第10版", Price=100.67,CreateTime=DateTime.Now},
    17                new Products(){Id=2,CategoryId=1, Name="Redis开发和运维", Price=69.9,CreateTime=DateTime.Now.AddDays(-19)},
    18                new Products(){Id=3,CategoryId=2, Name="活着", Price=57,CreateTime=DateTime.Now.AddMonths(-3)},
    19                new Products(){Id=4,CategoryId=3, Name="高等数学", Price=97,CreateTime=DateTime.Now.AddMonths(-1)}
    20             };
    21             // 注意:ThenBy()的方法语法和查询表达式写法有些不同。
    22             Console.WriteLine("方法语法升序排序");
    23             // 1、查询方法,按照商品分类升序排序,如果商品分类相同在按照价格升序排序 返回匿名类
    24             var list = listProduct.OrderBy(p => p.CategoryId).ThenBy(p=>p.Price).Select(p => new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime }).ToList();
    25             foreach (var item in list)
    26             {
    27                 Console.WriteLine($"item:{item}");
    28             }
    29             Console.WriteLine("查询表达式升序排序");
    30             var listExpress = from p in listProduct orderby p.CategoryId,p.Price select new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime };
    31             foreach (var item in listExpress)
    32             {
    33                 Console.WriteLine($"item:{item}");
    34             }
    35             Console.WriteLine("方法语法降序排序");
    36             // 1、查询方法,按照商品分类降序排序,如果商品分类相同在按照价格升序排序 返回匿名类
    37             var listDesc = listProduct.OrderByDescending(p => p.CategoryId).ThenBy(p => p.Price).Select(p => new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime }).ToList();
    38             foreach (var item in listDesc)
    39             {
    40                 Console.WriteLine($"item:{item}");
    41             }
    42             Console.WriteLine("查询表达式降序排序");
    43             var listExpressDesc = from p in listProduct orderby p.CategoryId descending , p.Price select new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime };
    44             foreach (var item in listExpressDesc)
    45             {
    46                 Console.WriteLine($"item:{item}");
    47             }
    48             Console.ReadKey();
    49         }
    50     }
    51 }

    结果:

     

    四、ThenByDescending

    ThenByDescending操作符于ThenBy操作符非常类似,只是是按照降序排序,实现按照次关键字对序列进行降序排列。来看看ThenByDescending的定义:
    从截图中可以看出:ThenByDescending()方法扩展的是IOrderedEnumerable<T>,因此ThenByDescending操作符也是常常跟在OrderBy和OrderByDesceding之后。看下面的例子:
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace OrderOperation
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             // 初始化数据
    14             List<Products> listProduct = new List<Products>()
    15             {
    16                new Products(){Id=1,CategoryId=1, Name="C#高级编程第10版", Price=100.67,CreateTime=DateTime.Now},
    17                new Products(){Id=2,CategoryId=1, Name="Redis开发和运维", Price=69.9,CreateTime=DateTime.Now.AddDays(-19)},
    18                new Products(){Id=3,CategoryId=2, Name="活着", Price=57,CreateTime=DateTime.Now.AddMonths(-3)},
    19                new Products(){Id=4,CategoryId=3, Name="高等数学", Price=97,CreateTime=DateTime.Now.AddMonths(-1)}
    20             };
    21             // 注意:ThenByDescending()的方法语法和查询表达式写法有些不同。
    22             Console.WriteLine("方法语法升序排序");
    23             // 1、查询方法,按照商品分类升序排序,如果商品分类相同在按照价格降序排序 返回匿名类
    24             var list = listProduct.OrderBy(p => p.CategoryId).ThenByDescending(p => p.Price).Select(p => new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime }).ToList();
    25             foreach (var item in list)
    26             {
    27                 Console.WriteLine($"item:{item}");
    28             }
    29             Console.WriteLine("查询表达式升序排序");
    30             var listExpress = from p in listProduct orderby p.CategoryId, p.Price descending select new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime };
    31             foreach (var item in listExpress)
    32             {
    33                 Console.WriteLine($"item:{item}");
    34             }
    35             Console.WriteLine("方法语法降序排序");
    36             // 1、查询方法,按照商品分类降序排序,如果商品分类相同在按照价格降序排序 返回匿名类
    37             var listDesc = listProduct.OrderByDescending(p => p.CategoryId).ThenByDescending(p => p.Price).Select(p => new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime }).ToList();
    38             foreach (var item in listDesc)
    39             {
    40                 Console.WriteLine($"item:{item}");
    41             }
    42             Console.WriteLine("查询表达式降序排序");
    43             var listExpressDesc = from p in listProduct orderby p.CategoryId descending, p.Price descending select new { id = p.CategoryId, ProductName = p.Name, ProductPrice = p.Price, PublishTime = p.CreateTime };
    44             foreach (var item in listExpressDesc)
    45             {
    46                 Console.WriteLine($"item:{item}");
    47             }
    48             Console.ReadKey();
    49         }
    50     }
    51 }

     结果:

    五、Reverse

    Reverse操作符用于生成一个与输入序列中元素相同,但元素排列顺序相反的新序列。下面来看看Reverse()方法的定义:

    1 public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source)

    从方法定义中可以看到,这个扩展方法,不需要输入参数,返回一个新集合。需要注意的是,Reverse方法的返回值是void。看下面的例子:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace ThenBy
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             string[] str = { "A", "B", "C", "D", "E"};
    14             var query = str.Select(p => p).ToList();
    15             query.Reverse();
    16             foreach (var item in query)
    17             {
    18                 Console.WriteLine(item);
    19             }
    20 
    21             Console.ReadKey();
    22         }
    23     }
    24 }

    运行效果:

  • 相关阅读:
    SPOJ GSS4 Can you answer these queries IV ——树状数组 并查集
    SPOJ GSS3 Can you answer these queries III ——线段树
    SPOJ GSS2 Can you answer these queries II ——线段树
    SPOJ GSS1 Can you answer these queries I ——线段树
    BZOJ 2178 圆的面积并 ——Simpson积分
    SPOJ CIRU The area of the union of circles ——Simpson积分
    HDU 1724 Ellipse ——Simpson积分
    HDU 1071 The area ——微积分
    HDU 4609 3-idiots ——FFT
    BZOJ 2194 快速傅立叶之二 ——FFT
  • 原文地址:https://www.cnblogs.com/dotnet261010/p/6850936.html
Copyright © 2011-2022 走看看