zoukankan      html  css  js  c++  java
  • C#的GroupBy方法是如何工作的

    前言:先贴结果

    GroupBy方法是如何工作的?

    一、准备6个待分组的学生对象

    class student
        {
            public string name;//姓名
            public int grade;//年级
    
            public student(string name, int grade)
            {
                this.name = name;
                this.grade = grade;
            }
        }
    List<student> students = new List<student>();
                for (int i = 0; i < 3; i++)
                {
                    students.Add(new student("学生" + i, 1));
                }
                for (int i = 0; i < 3; i++)
                {
                    students.Add(new student("学生" + (i+3), 2));
                }

    其中有3个1年级,3个2年级

    二、准备分组比较值产生器

    static int getGrade(student stu)
            {
                Console.WriteLine("分组关键字->	该学生的年级:" + stu.grade);
                return stu.grade;
            }

    分组方法将会调用此方法,得到分组依据

    三、准备分组比较器

    //学生年级相等比较器,如果分组关键字使用了学生对象,那么这里就可以用学生的其他属性进行相等比较,比如学生ID
        class studentComparer : IEqualityComparer<int>
        {
         //判断关键字是否相等,当然也可以是大于,平方,等任意规则
            public bool Equals(int x, int y)
            {
                if (x==y)
                {
    
                    Console.WriteLine("比较器->	学生年级相等:" + x + "年级");
                    return true;
                }
                else
                {
                    Console.WriteLine("学生年级不相等");
                    return false;
                }
            }
    
            public int GetHashCode(int x)
            {
                int code = x.GetHashCode();
                return code.GetHashCode();
            }
        }

    分组比较器将会对分组关键字进行比较,得到分组

    四、GroupBy()分组器

    //给GroupBy传入分组方法,ToList()执行分组时,程序对元素集中的每个元素调用"相等比较器"进行分组
                //得到一个包含几个分组对象IGrouping的枚举对象IEnumerable
                //每个分组对象IGrouping的属性是:(分组键值,分组元素集)
                //因此GroupBy方法属于js中的高级方法,就像map,reduce等
                //可以自定义"相等比较器"IEqualityComparer,自定义相等判断规则
                IEnumerable<IGrouping<int,student>> d = students.GroupBy<student, int>(getGrade,new studentComparer()).ToList();

    分组器将会采用一个尽可能减少比较次数的算法,使用比较器分组关键字比较

    在这个例子中,6个学生分两组只进行了4次比较,第一直觉是应该会用5次比较

    五、分组结果展示

    foreach (IGrouping<int,student> item in d)
               {
                   Console.WriteLine(item.Key+"年级:");
                   foreach (student stu in item)
                   {
                       Console.WriteLine("	名字:" + stu.name);
                   }
    
               }
               Console.WriteLine("系统的比较方法很厉害,只用4次比较,将6个元素分成了2组,采用2分法的方式似乎可以");
               Console.ReadLine();

    六、完整代码

    class Program
        {
            static void Main(string[] args)
            {
                //6个学生
                List<student> students = new List<student>();
                for (int i = 0; i < 3; i++)
                {
                    students.Add(new student("学生" + i, 1));
                }
                for (int i = 0; i < 3; i++)
                {
                    students.Add(new student("学生" + (i+3), 2));
                }
               //var d = students.GroupBy<student,int>(t => t.grade);//对studentList按照ClassCode分组
    
                //给GroupBy传入分组方法,ToList()执行分组时,程序对元素集中的每个元素调用"相等比较器"进行分组
                //得到一个包含几个分组对象IGrouping的枚举对象IEnumerable
                //每个分组对象IGrouping的属性是:(分组键值,分组元素集)
                //因此GroupBy方法属于js中的高级方法,就像map,reduce等
                //可以自定义"相等比较器"IEqualityComparer,自定义相等判断规则
                IEnumerable<IGrouping<int,student>> d = students.GroupBy<student, int>(getGrade,new studentComparer()).ToList();
               foreach (IGrouping<int,student> item in d)
               {
                   Console.WriteLine(item.Key+"年级:");
                   foreach (student stu in item)
                   {
                       Console.WriteLine("	名字:" + stu.name);
                   }
    
               }
               Console.WriteLine("系统的比较方法很厉害,只用4次比较,将6个元素分成了2组,采用2分法的方式似乎可以");
               Console.ReadLine();
            }
    
            static int getGrade(student stu)
            {
                Console.WriteLine("分组关键字->	该学生的年级:" + stu.grade);
                return stu.grade;
            }
        }
    
        class student
        {
            public string name;//姓名
            public int grade;//年级
    
            public student(string name, int grade)
            {
                this.name = name;
                this.grade = grade;
            }
        }
    
        //学生年级相等比较器,如果分组关键字使用了学生对象,那么这里就可以用学生的其他属性进行相等比较,比如学生ID
        class studentComparer : IEqualityComparer<int>
        {
    
            public bool Equals(int x, int y)
            {
                if (x==y)
                {
    
                    Console.WriteLine("比较器->	学生年级相等:" + x + "年级");
                    return true;
                }
                else
                {
                    Console.WriteLine("学生年级不相等");
                    return false;
                }
            }
    
            public int GetHashCode(int x)
            {
                int code = x.GetHashCode();
                return code.GetHashCode();
            }
        }
  • 相关阅读:
    Swift
    Swift
    Swift
    Swift
    iOS 判断某一日期是否在一日期区间
    iOS 本地推送通知
    iOS json解析中包含“ ”等解析出错
    iOS UILabel两侧加阴影
    IOS 设置ios中DatePicker的日期为中文格式
    [分享] 关于App Store下载到一半发生错误的问题 [复制链接]
  • 原文地址:https://www.cnblogs.com/ggtc/p/14521010.html
Copyright © 2011-2022 走看看