• 学习记录 C# IComparer接口 多字段排序,递进排序


    背景:

     工作中遇到这种排序场景,就不能单一使用System.Linq.Enumerable 中的扩展方法  OrderBy,OrderByDescending 排序方式了。

    实现该需求有不同的方式 记录一下:

    测试代码:

        public class Student
        {
            public string Name { get; set; }
    
            public int Age { get; set; }
    
            public int Height { get; set; }
    
            public int Weight { get; set; }
    
    
            public int Score { get; set; }
    
            public override string ToString()
            {
                return nameof(Name) + ":" + Name + "," + nameof(Age) + ":" + Age + "," + nameof(Height) + ":" + Height + "," + nameof(Weight) + ":" + Weight + "," + nameof(Score) + ":" + Score;
            }
        }
                List<Student> list = new List<Student> {
                new Student{ Name  = "Bob",Age = 29,Height = 180,Weight = 60,Score = 100},
                new Student{ Name  = "Foo",Age = 25,Height = 176,Weight = 67,Score = 89},
                new Student{ Name  = "Jam",Age = 25,Height = 176,Weight = 67,Score = 99},
                new Student{ Name  = "Alice",Age = 31,Height = 169,Weight = 66,Score = 87},
                new Student{ Name  = "Nura",Age = 31,Height = 160,Weight = 70,Score = 78}
                };

    1:使用内置的排序方式,硬编码不同的字段

    命名空间:System.Linq 下 有 ThenByDescending ,Enumerable.ThenBy 扩展方法 用于在 调用 OrderBy  OrderByDescending之后调用,按升序,降序 对序列中的元素执行后续排序。

     
    public static System.Linq.IOrderedEnumerable<TSource> ThenBy<TSource,TKey> (this System.Linq.IOrderedEnumerable<TSource> source, Func<TSource,TKey> keySelector);
        Console.WriteLine("排序前:");
                foreach (var item in list) Console.WriteLine(item.ToString());
    
                //测试升序排列:Age 排序 当Age相同 Height排序 当Height相同 Weight排序 当Weight相同 Score排序……
                Console.WriteLine();
                Console.WriteLine("System.Linq.Enumerable 中的扩展 内置排序:");
                list = list.OrderByDescending(c => c.Age).ThenBy(c => c.Height).ThenBy(c => c.Weight).ThenBy(c => c.Score).ToList();
                Console.WriteLine("排序后:");
                foreach (var item in list) Console.WriteLine(item.ToString());

    输出如下:

     

    2:通过实现IComparer<Student>接口 自定义排序

    示例代码:

       public class MyCompare : IComparer<Student>
        {
    
            /// <summary>
            /// 动态排序字段
            /// </summary>
            public readonly string[] PropNames;
            public MyCompare(string[] propNames)
            {
                //PropNames = string[]{ "Age", "Height", "Weight", "Score" };
                PropNames = propNames;
            }
    
            public int Compare(Student x, Student y)
            {
                int i = PropNames.Length;
                return InnerCompare(x, y, i);
            }
    
    
            private int InnerCompare(Student x, Student y, int i)
            {
    
                for (int j = 0; j < i; j++)
                {
                    var propName = PropNames[j];
                    var prop = typeof(Student).GetProperty(propName);
                    var xValue = prop.GetValue(x);
                    var yValue = prop.GetValue(y);
    
                    //当具有不同的数据类型
                    //if (xValue.GetType() == typeof(int))
    
                    int xCurrentPropValue = Convert.ToInt32(xValue);
                    int yCurrentPropValue = Convert.ToInt32(yValue);
                    if (xCurrentPropValue != yCurrentPropValue)
                    {
                        return xCurrentPropValue.CompareTo(yCurrentPropValue);
                    }
                    else
                    {
                        return InnerCompare(x, y, j + 1);
                    }
                }
                return 0;
            }
    
    
        }
     输出如下:

    说明:

    C#中有 IComparable、IComparer接口

    前者 定义通用比较方法 排序实现的最底层逻辑,后者定义排序方式 借助于IComparable接口

    如示例代码中的  return xCurrentPropValue.CompareTo(yCurrentPropValue); CompareTo方法还是依赖于默认实现了的IComparable接口中的 CompareTo方法。

     
  • 相关阅读:
    车辆路径规划问题分类
    启发算法 汇总篇
    蚁群算法【2】 优化方法
    注意力机制【1】入门讲解
    中值滤波 进阶篇
    峭度系数
    注意力机制【2】 CV中的注意力机制
    Mac免密登录
    windows linux子系统对外提供服务的俩种方法
    离线安装python包
  • 原文地址:https://www.cnblogs.com/camefor/p/16197994.html
Copyright © 2020-2023  润新知