zoukankan      html  css  js  c++  java
  • LINQ之延迟执行标准查询操作符(中)

    操作符:Concat

    描述:用于连接2个序列

    原型:1种

    public static IEnumerable<TSource> Concat<TSource>(
    	this IEnumerable<TSource> first,
    	IEnumerable<TSource> second
    )
    
                string [] dogs = {"kelly","belly","shelly"};
                string[] cats = {"kiti", "lili"};
    
                var pets = dogs.Concat(cats);
    
                foreach (var pet in pets)
                {
                    Console.WriteLine(pet);
                }

     

    返回的结果是:

    kelly

    belly

    shelly

    kiti

    lili

     

    操作符:OrderBy

    描述:允许输入序列根据一个keySelector方法进行升序排序,并返回一个排序后的结果:IOrderedEnumerable<TSource>

    原型:2种

     

    原型一:

     

    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    	this IEnumerable<TSource> source,
    	Func<TSource, TKey> keySelector
    )
    
    

    在这种原型中,TKey必须是实现了IComparable<TKey>

                string [] dogs = {"kelly","belly","shelly"};
                string[] cats = {"kiti", "lili"};
    
                var pets = dogs.Concat(cats).OrderBy(item=>item);
    
                foreach (var pet in pets)
                {
                    Console.WriteLine(pet);
                }

    需要注意的是,OrderBy后返回的是一个已经排序的结果:IOrderedEnumerable<TSource>,此时我们不应该在对这个序列调用OrderBy方法,

    因为这样会破坏原有的OrderBy的排序,如果我们需要再次针对其他的key进行排序,可以调用ThenBy,稍后会提到。

    原型二:

    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    	this IEnumerable<TSource> source,
    	Func<TSource, TKey> keySelector,
    	IComparer<TKey> comparer
    )
    

    原型二和原型一很类似,只是多提供了一个IComparer的参数,允许我们传入自己的排序算法。这样子的话,TKey就不一定要是想IComparer接口了。

    我们还是来看个例子:

    我们有一个Student类:

    public class Student
        {
            public string Name { get; set; }
    
            public List<int > Scores { get; set; }
        }

    我们希望根据Student的Scores的和来做一个降序排序,因此,我们另外建一个类来实现IComparer:

    public class SortStudentScore:IComparer<Student>
        {
            public int Compare(Student x, Student y)
            {
                decimal xScores = x.Scores.Sum(item => item);
                decimal yScores = y.Scores.Sum(item => item);
    
                return yScores.CompareTo(xScores);
            }
        }

    这样,我们的查询可以写成:

    //定义数据源
                List<Student> students = new List<Student>
                                               {
                                                   new Student{Name = "Terry",Scores = new List<int>{98,88,93,75,82}},
                                                   new Student{Name = "Tina",Scores = new List<int>{85,99,87,93,97}},
                                                   new Student{Name = "Linda",Scores = new List<int>{57,100,83,89,92}},
                                                   new Student{Name = "Leon",Scores = new List<int>{100,98,72,77,84}},
                                                   new Student{Name = "Echo",Scores = new List<int>{79,80,97,55,88}}
                                               };
                SortStudentScore sortStudentScore = new SortStudentScore();
                //定义查询表达式,找出不及格的学生及其分数
                var scoreQuery = students.OrderBy((s => s),sortStudentScore).Select(item=>new {item.Name,TotalScore= item.Scores.Sum(score=>score)});
    
                //输出结果)
                foreach (var query in scoreQuery)
                {
                    Console.WriteLine("Student:{0} TotalScore:{1}", query.Name, query.TotalScore);
                }

    我们的输出结果就是:

    Student:Tina TotalScore:461
    Student:Terry TotalScore:436
    Student:Leon TotalScore:431
    Student:Linda TotalScore:421
    Student:Echo TotalScore:399

    操作符:OrderByDescending

    描述:与OrderBy操作符类似,只是排序方式是按照降序来排序的。

    原型:与OrderBy一样,支持2种原型

    具体例子可以参照OrderBy的,不再赘述。

    操作符:ThenBy

    描述:将一个已经排序后的序列,根据新的key进行再排序。主要,与大多数LINQ操作不一样的地方是,ThenBy(以及后面要介绍的ThenByDescending)的输入序列都必须是实现了

    IOrderedEnumerable<T>。由于ThenBy是稳定排序,因此对于OrderBy/OrderByDescending后,ThenBy的key相同的2个元素,不会再打乱其排序。

    原型:2种,跟OrderBy一样

    为了说明这点,我们举个例子:

    //定义数据源
                List<Student> students = new List<Student>
                                               {
                                                   new Student{Id = 1,Name = "Leon",Scores = new List<int>{98,88,93,75,82}},
                                                   new Student{Id = 2,Name = "Tina",Scores = new List<int>{85,99,87,93,97}},
                                                   new Student{Id = 3,Name = "Linda",Scores = new List<int>{57,100,83,89,92}},
                                                   new Student{Id = 4,Name = "Leon",Scores = new List<int>{100,98,77,77,84}},
                                                   new Student{Id = 5,Name = "Echo",Scores = new List<int>{79,80,97,55,88}}
                                               };
                SortStudentScore sortStudentScore = new SortStudentScore();
    
                var orderByScoreQuery = students.OrderBy((s => s), sortStudentScore).
                                        Select(item => new {item.Id, item.Name, TotalScore = item.Scores.Sum(score => score) });
    
                Console.WriteLine("Using OrderBy only");
                //输出结果));
                foreach (var query in orderByScoreQuery)
                {
                    Console.WriteLine("{0}.{1} TotalScore:{2}",query.Id, query.Name, query.TotalScore);
                }
                Console.WriteLine();
                Console.WriteLine("After add ThenBy");
                //定义查询表达式,找出不及格的学生及其分数
                var scoreQuery = students.OrderBy((s => s), sortStudentScore).
                                        ThenBy(item=>item.Name).
                                        Select(item => new {item.Id, item.Name, TotalScore = item.Scores.Sum(score => score) });
    
                //输出结果)
                foreach (var query in scoreQuery)
                {
                    Console.WriteLine("{0}.{1} TotalScore:{2}", query.Id, query.Name, query.TotalScore);
                }

    为了说明这个例子,我们让两个学生同名,并且总分也一样,用Id来区别他们,以下是输出结果:

    Using OrderBy only
    2.Tina TotalScore:461
    1.Leon TotalScore:436
    4.Leon TotalScore:436
    3.Linda TotalScore:421
    5.Echo TotalScore:399

    After add ThenBy
    2.Tina TotalScore:461
    1.Leon TotalScore:436
    4.Leon TotalScore:436
    3.Linda TotalScore:421
    5.Echo TotalScore:399

    我们发现Id 1和Id 4经过ThenBy后,并没有调整顺序。对于像List.Sort<T>这种不稳定排序,相同的值排序后可能打乱掉原有的顺序的。

    操作符:Reverse

    描述:Reverse很简单,就是将序列逆序一下

    原型:

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

    看个简单的例子吧:

    int[] nums = new int[] { 0,1,2,3,4,5 };
    
                var evenNums = nums.Reverse();
    
                foreach (var evenNum in evenNums)
                {
                    Console.WriteLine(evenNum);
                }

    输出的结果为:

    5
    4
    3
    2
    1
    0


    To Be Continue…

    参考:《Pro.LINQ.Language.Integrated.Query.in.Csharp.2010》

  • 相关阅读:
    使用IDEA模拟git命令使用的常见场景
    解决 No converter found for return value of type: class java.util.ArrayList
    Connections could not be acquired from the underlying database! ### The error may exist in mapper/BookMapper.xml
    There is no PasswordEncoder mapped for the id "null"
    The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone
    MySQL错误:2003-Can't connect to MySQL server on 'localhost'(10061 "unknown error")
    镜像源
    读书笔记 Week5 2018-4-5
    [第五周课后作业] 软件创新分析
    C#入门学习笔记
  • 原文地址:https://www.cnblogs.com/tian2010/p/2400574.html
Copyright © 2011-2022 走看看