当前位置: 首页 > article >正文

【一文读懂】C#如何实现通用的排序功能

目录

通用排序功能

1.升序

2.降序

测试

1.测试代码

2.测试结果 


      本篇文章来分享一下C#如何实现通用的排序功能。在项目中经常会使用到排序的方法,那如何使排序方法更加通用呢?可以通过泛型,接口,委托来实现。

通用排序功能

1.升序

        为了方便理解,从基本数据类型(int)进行分析,以冒泡排序为例

/// <summary>
/// 整型数组升序排序(冒泡排序)
/// </summary>
/// <param name="array">数组</param>
public static void OrderByInt(int[] array)
{
    for (int i = 0; i < array.Length; ++i)
    {
        for (int j = i + 1; j < array.Length; j++)
        {
            if (array[i] > array[j])
            {
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

        如果也要对字符串(string)进行比较,那就可以使用比较方法CompareTo

/// <summary>
/// 整型数组升序排序(冒泡排序)
/// </summary>
/// <param name="array">数组</param>
public static void OrderByInt(int[] array)
{
    for (int i = 0; i < array.Length; ++i)
    {
        for (int j = i + 1; j < array.Length; j++)
        {
            if (array[i].CompareTo(array[j]) > 0)
            {
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

/// <summary>
/// string数组升序排序(冒泡排序)
/// </summary>
/// <param name="array">数组</param>
public static void OrderByString(String[] array)
{
    for (int i = 0; i < array.Length; ++i)
    {
        for (int j = i + 1; j < array.Length; j++)
        {
            if (array[i].CompareTo(array[j]) > 0)
            {
                String temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

         要想更加适用,就可以使用泛型,并使用接口约束,只要提供了比较方法的的类型,就可以进行排序

/// <summary>
/// 任何数据类型数组升序排序(冒泡排序)
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="array">数组</param>
public static void OrderByType<T>(T[] array) where T : IComparable<T>
{
    for (int i = 0; i < array.Length; ++i)
    {
        for (int j = i + 1; j < array.Length; j++)
        {
            if (array[i].CompareTo(array[j]) > 0)
            {
                T temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

         那如果要进行排序的类型是复合数据类型,想要按照该类型指定的属性进行排序,该怎么处理呢?我们可以通过接口来实现属性的比较方法。Student类有一个默认字段(Id)的排序方法,若还想通过Age进行排序,可以通过比较器来实现

/// <summary>
/// 任何数据类型数组,按照该类型指定的属性进行升序排序(冒泡排序)
/// <typeparam name="T">数据类型</typeparam>
/// <param name="array">数组</param>
/// <param name="comparer">比较器</param>
public static void OrderByTypeAndProperty<T>(T[] array, IComparer<T> comparer) where T : IComparable<T>
{
    for (int i = 0; i < array.Length; ++i)
    {
        for (int j = i + 1; j < array.Length; j++)
        {
            if (comparer.Compare(array[i], array[j]) > 0)
            {
                T temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

public class Student : IComparable<Student>
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public int CompareTo(Student obj)
    {
        return Id.CompareTo(obj.Id);
    }
}

public class AgeComparer : IComparer<Student>
{
    public int Compare(Student x, Student y)
    {
        return x.Age.CompareTo(y.Age);
    }
}

         此时发现使用接口时,如果要排序的属性不同,则要实现多个方法,代码不够简洁,也不便于维护,而委托就解决了这些问题,注意委托定义在类外

/// <summary>
/// 选择委托
/// 返回数据类型T的属性Tkey的值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <typeparam name="Tkey">数据类型T的字段</typeparam>
/// <returns>选择的属性</returns>
public delegate TKey SelectHandler<T, TKey>(T t);//注意是写在类外

/// <summary>
/// 使用委托对任何数据类型数组进行升序排序
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <typeparam name="Tkey">数据类型T的字段</typeparam>
/// <param name="array">数据类型T的数组</param>
/// <param name="selectHandler">选择委托的对象</param>
public static void OrderBy<T, Tkey>(T[] array, SelectHandler<T, Tkey> selectHandler)
    where Tkey : IComparable<Tkey>
{
    for (int i = 0; i < array.Length; ++i)
    {
        for (int j = i + 1; j < array.Length; ++j)
        {
            //将委托已经取得数据类型的属性的进行比较
            if (selectHandler(array[i]).CompareTo(selectHandler(array[j])) > 0)
            {
                T temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

2.降序

         降序排序同理

/// <summary>
/// 使用委托对任何数据类型数组进行降序排序
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <typeparam name="Tkey">数据类型T的字段</typeparam>
/// <param name="array">数据类型T的数组</param>
/// <param name="selectHandler">选择委托的对象</param>
public static void OrderByDescending<T, Tkey>(T[] array, SelectHandler<T, Tkey> selectHandler)
    where Tkey : IComparable<Tkey>
{
    for (int i = 0; i < array.Length; ++i)
    {
        for (int j = i + 1; j < array.Length; ++j)
        {
            //将委托已经取得数据类型的属性的进行比较
            if (selectHandler(array[i]).CompareTo(selectHandler(array[j])) < 0)
            {
                T temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

测试

1.测试代码

using System;
using UnityEngine;

namespace SortTest
{
    /// <summary>
    /// 选择委托
    /// 返回数据类型T的属性Tkey的值
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <typeparam name="Tkey">数据类型T的字段</typeparam>
    /// <returns>选择的属性</returns>
    public delegate TKey SelectHandler<T, TKey>(T t);//注意是写在类外

    public class SortTest : MonoBehaviour
    {
        private void Start()
        {
            //int[]
            int[] intArray = { 4, 1, 5, 0 };
            SortTestByType(intArray,(value)=> { return value; });
            //string[]
            string[] stringArray = { "2","a","ab","hello","0" };
            SortTestByType(stringArray, (value) => { return value; });
            //Student[]
            Student[] studentArray = 
            {
                new Student(){ Id=1001,Name="张三",Age=20 },
                new Student(){ Id=1003,Name="李四",Age=18 },
                new Student(){ Id=1002,Name="赵六",Age=21 },
                new Student(){ Id=1000,Name="王五",Age=19 }
            };
            SortTestByType(studentArray, (studentArray) => { return studentArray.Id; });
            SortTestByType(studentArray, (studentArray) => { return studentArray.Name; });
            SortTestByType(studentArray, (studentArray) => { return studentArray.Age; });
        }

        private void SortTestByType<T, Tkey>(T[] array, SelectHandler<T, Tkey> selectHandler)
            where Tkey : IComparable<Tkey>
        {
            Debug.Log(array.GetType()+"测试:");
            OrderBy(array, selectHandler);
            PrintSortedArray(array, selectHandler);
            OrderByDescending(array, selectHandler);
            PrintSortedArray(array, selectHandler);
        }

        private void PrintSortedArray<T, Tkey>(T[] array, SelectHandler<T, Tkey> selectHandler)
            where Tkey : IComparable<Tkey>
        {
            string sortedStr="";
            for (int i = 0; i < array.Length; i++)
            {
                sortedStr += selectHandler(array[i]).ToString()+" ";
            }
            Debug.Log(sortedStr);
        }

        /// <summary>
        /// 使用委托对任何数据类型数组进行升序排序
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <typeparam name="Tkey">数据类型T的字段</typeparam>
        /// <param name="array">数据类型T的数组</param>
        /// <param name="selectHandler">选择委托的对象</param>
        public static void OrderBy<T, Tkey>(T[] array, SelectHandler<T, Tkey> selectHandler)
            where Tkey : IComparable<Tkey>
        {
            for (int i = 0; i < array.Length; ++i)
            {
                for (int j = i + 1; j < array.Length; ++j)
                {
                    //将委托已经取得数据类型的属性的进行比较
                    if (selectHandler(array[i]).CompareTo(selectHandler(array[j])) > 0)
                    {
                        T temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 使用委托对任何数据类型数组进行降序排序
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <typeparam name="Tkey">数据类型T的字段</typeparam>
        /// <param name="array">数据类型T的数组</param>
        /// <param name="selectHandler">选择委托的对象</param>
        public static void OrderByDescending<T, Tkey>(T[] array, SelectHandler<T, Tkey> selectHandler)
            where Tkey : IComparable<Tkey>
        {
            for (int i = 0; i < array.Length; ++i)
            {
                for (int j = i + 1; j < array.Length; ++j)
                {
                    //将委托已经取得数据类型的属性的进行比较
                    if (selectHandler(array[i]).CompareTo(selectHandler(array[j])) < 0)
                    {
                        T temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }
    }
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

2.测试结果 

         好了,今天的分享到这里就结束啦,希望对你有所帮助~


http://www.kler.cn/news/328641.html

相关文章:

  • 车辆重识别(利用扩散模型合成有效数据进行行人再识别预训练)论文阅读2024/9/27
  • 【树莓派系列】树莓派首次开机配置
  • LeetCode 面试经典150题 50.Pow(x,n)
  • VMware 设置静态IP
  • 鸿蒙开发(NEXT/API 12)【硬件(取消注册智慧出行连接状态的监听)】车载系统
  • 记录Mybatis分页查询排序问题: Encountered unexpected token: “and“ “AND“
  • C++:STL(四)之vector的基本介绍与使用方式|容器接口
  • Python NumPy 数据分析:处理复杂数据的高效方法
  • 数据结构-3.9.栈在递归中的应用
  • React、Vue.js和Angular三大主流框架的选择对比
  • yum使用阿里云的镜像源报错 Failed connect to mirrors.aliyuncs.com:80; Connection refused“
  • 智能工厂非标自动化集成商
  • 【Python】数据可视化之点线图
  • trixbox call php发起电话呼叫
  • Vortex GPGPU的github流程跑通与功能模块波形探索
  • 回执单识别-银行回单识别API-文字识别OCR API
  • 解决 Git LFS 切换分支失败问题
  • Android AMS介绍
  • PCL LocalMaximum消除局部最大的点
  • Egress Gateway 是一个重要的组件,用于管理从服务网格内部到外部服务的流量
  • scrapy快速上手
  • Mybatis-Plus新花样(二)
  • Robot Operating System——带有协方差矩阵的三维空间中的位姿(位置和方向)
  • 基于 Seq2Seq 的中英文翻译项目(pytorch)
  • 番外篇 | 复现AC-YOLOv5,进行自动化织物缺陷检测
  • Mybatis 9种动态 sql 标签使用
  • 基于深度学习的任务序列中的快速适应
  • 基于微信小程序的宿舍报修系统的设计与实现(lw+演示+源码+运行)
  • 正交阵的概念、性质与应用
  • 激光切割机适用材质有哪些