排序操作中的小陷阱

来源:互联网 发布:常见的网络攻击类型 编辑:程序博客网 时间:2024/05/22 20:46

排序是开发过程中被经常使用的操作。

作为开发者,由于自己的不小心,可能会使自己掉进排序的一个小陷阱。

那么这个小陷阱是什么呢?

 

直接上实例代码,看完代码大家就明白了。

using System;using System.Collections.Generic;using System.Linq; namespace LinqGroupByExp{    public class Student    {        public int Id { get; set; }        public string Name { get; set; }        public int Age { get; set; }        public string Sex { get; set; }        public int ClassId { get; set; }    }     class Program    {        static void Main(string[] args)        {            List<Student> studentList = new List<Student>();            studentList.Add(new Student() { Id = 1, Name = "zhangy", Age = 23, Sex = "girl", ClassId = 1 });            studentList.Add(new Student() { Id = 2, Name = "yul", Age = 21, Sex = "boy", ClassId = 2 });            studentList.Add(new Student() { Id = 3, Name = "wsp", Age = 25, Sex = "girl", ClassId = 2 });            studentList.Add(new Student() { Id = 4, Name = "songl", Age = 22, Sex = "girl", ClassId = 1 });            studentList.Add(new Student() { Id = 5, Name = "wuj", Age = 23, Sex = "boy", ClassId = 2 });            studentList.Add(new Student() { Id = 6, Name = "liuy", Age = 20, Sex = "boy", ClassId = 1 });            studentList.Add(new Student() { Id = 7, Name = "wengj", Age = 24, Sex = "girl", ClassId = 2 });            studentList.Add(new Student() { Id = 8, Name = "lipo", Age = 22, Sex = "boy", ClassId = 1 });             Console.WriteLine("*******************************************************************");            Console.WriteLine("原始数据:");            foreach (var s in studentList)            {                Console.WriteLine(" Id = " + s.Id + ", "+                    " Name = " + s.Name + ", "+                    " Age = " + s.Age + ", "+                    " Sex = " + s.Sex + ", "+                    " ClassId = " + s.ClassId);            }            Console.WriteLine("*******************************************************************");            Console.WriteLine();             var studentOrderedList1 = studentList.OrderBy(it => it.ClassId);            var studentOrderedList2  =  studentOrderedList1.OrderBy(it => it.Age);             Console.WriteLine("*******************************************************************");            Console.WriteLine("两次使用OrderBy排序后的结果:");            foreach (var s in studentOrderedList2)            {                Console.WriteLine(" Id = " + s.Id + ", " +                    " Name = " + s.Name + ", " +                    " Age = " + s.Age + ", " +                    " Sex = " + s.Sex + ", " +                    " ClassId = " + s.ClassId);            }            Console.WriteLine("*******************************************************************");            Console.WriteLine();              var studentOrderedList = studentList.OrderBy(it => it.ClassId).ThenBy(it => it.Age);             Console.WriteLine("*******************************************************************");            Console.WriteLine("先使用OrderBy排序,再使用ThenBy排序后的结果:");            foreach (var s in studentOrderedList)            {                Console.WriteLine(" Id = " + s.Id + ", " +                    " Name = " + s.Name + ", " +                    " Age = " + s.Age + ", " +                    " Sex = " + s.Sex + ", " +                    " ClassId = " + s.ClassId);            }            Console.WriteLine("*******************************************************************");            Console.WriteLine();        }    }} 

代码中先定义学生列表studentList并向列表添加8条示例数据,接着使用两种方式对studentList列表进行排序并输出结果。

下面重点说说这两种排序。

排序1:使用OrderBy对集合进行两次排序,第一次按照学生的ClassId排序,第二次按照学生的Age排序。

排序2:使用OrderBy+ThenBy对集合进行排序,同样是先按照学生的ClassId排序,再按照学生的Age排序。

那么,问题来了,上面所述的两种排序方法得到的结果相同吗?

答案:自己往下看,下面是代码的执行结果。

 

从结果可以了解到:两种排序方法的结果并不相同。

下面对结果做简单的分析。

对于排序1先按照学生的ClassId排序得到集合studentOrderedList1,此时集合中数据的显示顺序由学生的ClassId来决定。接着,再对集合studentOrderedList1中的数据按照学生的Age来排序,得到集合studentOrderedList2 ,此时集合中数据的显示顺序由学生的Age来决定,所以当我们输出集合studentOrderedList2 中的数据时,发现显示顺序由Age决定而与ClassId无关。也就是说,使用OrderBy对集合进行多次排序后,得到的结果中的数据的顺序由最后一次的排序来决定,后次排序覆盖了前次排序。

对于排序2:但是,我们在开发中,经常需要先对集合按照某个字段排序,排序后,再在不影响前次排序结果的条件下按照另一个字段来排序,也就是说最终数据的排列顺序由多个字段来决定时,我们就可以使用OrderBy+ThenBy的方式来实现。例子中使用OrderBy+ThenBy排序得到的最终结果便是由ClassId+Age两个字段来决定的,所有数据先按照ClassId排序,ClassId相同的数据再按照Age来排序。

分析完实验结果,我们来说说文章一开始提到的那个小陷阱吧。

开发时我们往往想要的排序效果正是排序2所达到的效果,但是由于自己考虑不周到,可能会错误的认为排序1同样能达到我们的效果,于是在代码中错误的使用排序1来达到我们想要的效果,结果可想而知了。

这里的小陷阱,与其说是排序的小陷阱,还不如说是认识上的小陷阱,你说是吗。

 

0 0
原创粉丝点击