【一文读懂】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.xdnf.cn/news/1548620.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

再也不用担心内容重复!在线伪原创工具,让创作更自由!

大家好&#xff0c;今天我们将讨论一个对网络写作非常有益的辅助工具——在线内容转换工具。不论您是需要更新您的博客&#xff0c;还是希望在社交平台上保持活跃&#xff0c;我们都频繁面临着迅速生成新内容的挑战。利用一个有效的工具来改写现有内容&#xff0c;可以极大地提…

机器学习笔记(李宏毅老师2021/2022课程)【更新中】

目录 前言 课程预览 第一讲 机器学习基本概念 前言 本文主要记录在听李宏毅老师的课时对应做的课堂笔记 课程&#xff1a; (强推)李宏毅2021/2022春机器学习课程_哔哩哔哩_bilibili 课程预览 机器学习找函数 &#xff08;找一个人类写不出来的复杂函数&#xff09; 课程侧…

Splashtop 自收购 Foxpass 以来新业务增长62%

2024年9月24日 加利福尼亚州库比蒂诺 Splashtop 在简化远程办公解决方案领域处于领先地位&#xff0c;今天宣布继去年收购 Foxpass 之后&#xff0c;新的 Foxpass 业务实现了62%的增长。Splashtop 的 Foxpass Cloud RADIUS 可确保企业 Wi-Fi 网络安全&#xff0c;防止未经授权…

PaddleOCR 表格识别,docker部署,cpu版本

前置环境 centeros7 docker 拉取镜像 docker pull registry.baidubce.com/paddlepaddle/paddle:2.6.1 参考&#xff1a;开始使用_飞桨-源于产业实践的开源深度学习平台 这里拉取的镜像并不能立马用&#xff0c;只是内置好运行环境 随便找个目录下载paddleocr的代码 git…

死磕P7: JVM垃圾回收那点事,轻松拿捏不是事儿(二)

这是「死磕P7」系列第 004 篇文章&#xff0c;欢迎大家来跟我一起 死磕 100 天&#xff0c;争取在 2025 年来临之际&#xff0c;给自己一个交代。&#xff08;公&号&#xff1a;新质程序猿&#xff0c;更新会更及时&#xff0c;内容也会更全面丰富&#xff0c;欢迎大家关注…

神仙级AI产品经理入门手册,从入门到入魂非常详细,收藏这一篇,少走三年弯路!!!

作为一个产品经理&#xff0c;你可能已经熟悉了一些常见的AI技术和应用&#xff0c;比如机器学习、深度学习、自然语言处理、计算机视觉等。 但是&#xff0c;你是否了解什么是大模型&#xff1f;大模型又有什么特点和优势&#xff1f;为什么大模型会成为AI领域的一个重要趋势…

Llama系列迈向多模态新时代:3.2版本开源超越闭源,并携手Arm推出手机优化版

在多模态领域&#xff0c;开源模型也超闭源了&#xff01; 就在刚刚结束的 Meta 开发者大会上&#xff0c;Llama 3.2 闪亮登场&#xff1a; 这回不仅具备了多模态能力&#xff0c;还和 Arm 等联手&#xff0c;推出了专门为高通和联发科硬件优化的 “移动” 版本。 具体来说&a…

尾矿库安全监测系统:守护矿山安全的关键技术

尾矿库是矿山企业用于存放尾矿的重要设施&#xff0c;其安全状况直接关系到周边环境和人民生命财产安全。近年来&#xff0c;随着技术的不断进步&#xff0c;尾矿库安全监测系统应运而生&#xff0c;为尾矿库的安全管理提供了强有力的技术支持。本文将详细介绍尾矿库安全监测系…

en造数据结构与算法C# 之 二叉排序树的删除

en造数据结构与算法C# 之 二叉排序树的增/查-CSDN博客 删除方法比起添加和查找就稍显复杂了 &#xff0c;所以单独拿出来写一篇 分析 输入 1.根节点&#xff0c;用于从根上查找你要删除的节点 2.需要删除的值 public Node<T> Delete(Node<T> root, T data) {if (…

设计模式、系统设计 record part02

软件设计模式&#xff1a; 1.应对重复发生的问题 2.解决方案 3.可以反复使用 1.本质是面向对象 2.优点很多 1.创建型-创建和使用分离 2.结构型-组合 3.行为型-协作 571123种模式 UML-统一建模语言-Unified Modeling Language 1.可视化&#xff0c;图形化 2.各种图&#xff08;9…

SSH连接提示秘钥无效

说明&#xff1a;本文记录一次使用SSH连接服务器失效的问题。 使用SSH命令连接服务器&#xff0c; ssh -i ssh秘钥路径 user192.xx.xx.xx提示下面的错误&#xff1b; Load key "shuhe.bin": invalid format aochuang192.xx.xx.xx: Permission denied (publickey,g…

Python新手学习过程记录之基础环境:环境变量、版本区分、虚拟环境

https://img-blog.csdnimg.cn/img_convert/0604267530a515112e51dfc80d0b0ee7.png 刚开始接触Python并学习一门开发语言,可能就会遇到一些棘手的问题,比如电脑上不知不觉已经安装了多个python版本,python3.8/3.10/3.11,甚至一些软件中也集成有python解释器&#xff1b;那么我编…

每日一题|2516. 每种字符至少取 K 个|双指针、最长子串、字典

本题需要转化求解目标。 对于一个序列&#xff0c;两头收集的最少数量的时候&#xff0c;剩下的部分&#xff08;我们称之为子串&#xff09;就会对应的越长。也就是说&#xff0c;我们只要求解一个满足要求的最长子串&#xff0c;使得两边剩余的字符数量刚好满足要求。 由于…

实时美颜功能技术揭秘:视频美颜SDK与API的技术剖析

当下&#xff0c;用户希望在视频直播中呈现出最佳状态&#xff0c;这推动了视频美颜SDK和API的迅速发展。本文将深入剖析这项技术的核心原理、应用场景以及未来趋势。 一、实时美颜技术的基本原理 在实现这些效果的过程中&#xff0c;视频美颜SDK通常会使用以下几种技术&…

Geekbench6使用指南:Linux系统性能测试,如此简单!

在当今计算机性能日益重要的时代&#xff0c;Geekbench 成为了测试 CPU 性能的热门工具。本文将带你深入了解如何使用 Geekbench&#xff0c;让你的电脑性能一目了然。 1. 什么是 Geekbench&#xff1f; Geekbench 是一款跨平台的基准测试工具&#xff0c;能够评估单核和多核…

Ubuntu Server 20.04 64bit定时备份MySQL8.0.36数据库数据

一、编写sh脚本 常见备份命令介绍 我选用的是mysqldump命令&#xff0c;命令使用简介 [root]> mysqldump -helpUsage: mysqldump [OPTIONS] database_name [tables] OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] OR mysqldump [OPTIONS] --all…

字节软件测试岗二面:APP测试问题被虐哭了,直到看到这些知识点

APP测试一直是大厂软件测试问到的一个重点细节&#xff0c;下面我来给大家展示一下大厂关于APP测试经常会问到的一些问题&#xff0c;以及解析。想象一下当你遇到面试官问到你这些问题时&#xff0c;你是否也能够对答如流哦&#xff01; 注意&#xff0c;注意啦&#xff01;小编…

对抗攻击方法详解:梯度攻击、转移攻击与模型集成攻击

对抗攻击方法详解&#xff1a;梯度攻击、转移攻击与模型集成攻击 近年来&#xff0c;随着深度学习模型在各个领域取得惊人突破&#xff0c;对抗攻击&#xff08;Adversarial Attack&#xff09; 逐渐成为研究热点。对抗攻击旨在通过在输入数据上施加精心设计的微小扰动&#x…

Meta号称替代程序员的LlamaCoder效果被CodeFlying秒杀,来看实测!

在讲LlamaCoder之前咱先浅聊一下Meta 这两天Meta凭借着Connect 2024大会可谓是风头正盛&#xff0c;刚刚发布的全新开源多模态大模型Llama3.2&#xff0c;热度是一路赶超咱的小草莓啊。 作为一款开源大模型能够和闭源的4o-mini、Claude3 Haiku打的有来有回&#xff0c; 甚至L…

32. Java栈和队列

1. 前言 栈和队列相关的题目是校招中出现频率一般,但是是属于相对基础的题型。我们要关注两类问题,栈和队列的添加和删除操作,以及栈和队列之间的区别和联系。 2. 栈和队列 2.1 数据结构 首先我们给出栈和队列的数据结构定义: (1)栈(Stack):允许在某一端插入元素(…