【C# 技术】 C# 常用排序方式——自定义数据排序

C# 常用排序方式——自定义数据排序
 前言

 在最近的项目中经常会对C#中的数据进行排序,对于基本数据类型,其排序方式比较简单,只需要调用内置算法即可实现,但对于自定义数据类型以及自定义排序规则的情况实现起来就比较麻烦,所以在本文章中将详细介绍一下在中C#中如何对数据进行排序。

 应用技术:  LINQ;   Array.Sort();

文章目录

  • 1. 使用Sort排序
  • 2. 使用LINQ语句进行排序
  • 3. 多条件排序
  • 4. 多维数据排序
  • 5. 总结

​ 下面我们进行自定义数据进行排序,如下面代码所示,我们在此处定义了一个 Person类,并且继承了IComparable<Person>接口,该接口主要是用于后面调用Sort方法所必需的接口。

class Person : IComparable<Person>
{public string name { get; set; }public int age { get; set; }public int id { get; set; }public int CompareTo(Person? other){if (this.age > other.age) { return 1; }else { return -1; }}public override string ToString(){return "(id: " + id + ", name: " + name + ", age: " + age + ")";}
};

1. 使用Sort排序

  对于自定义数据,我们可以使用Sort方法直接进行排序,默认是采用正序进行排序,此处提供了三种方式:

  • 方式一:使用默认的Sort()方法直接就可以进行排序,但是需要自定义数据继承IComparable<T>接口
  • 方式二:使用Sort()方法并添加回调函数,回调函数调用数据类型CompareTo()方法,该方法可以进行自定义。
  • 方式三:使用Sort()方法并添加回调函数,回调函数进行自定义,此处采用三目运算符写了个简单的方法,该方式无需继承继承IComparable<T>接口以及在自定义数据中添加比较函数。

  代码如下所示:

static void test_person_sort()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);// 1. 方式一list.Sort();// 2. 方式二list.Sort((x, y) => x.CompareTo(y));// 3. 方式三list.Sort((x, y) => x.age > y.age ? 1 : -1);print_array(list);}

  排序后结果输出为:

在这里插入图片描述

  如果想进行逆序排序,需要修改一下比较规则

static void test_person_sort_()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);// 1. 方式一list.Sort((x, y) => y.CompareTo(x));// 2. 方式二list.Sort((x, y) => x.age > y.age ? -1 : 1);print_array(list);}

  逆序排序后的输出为

在这里插入图片描述

2. 使用LINQ语句进行排序

  接下来介绍一下使用LINQ语句进行排序,LINQ是一组用于C#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。在此处我们可以使用两种方式实现:

  • 方式一:使用原生的LINQ语句进行查询,此处主要通过自己写LINQ语句;在使用时要注意一点,如果自定义数据继承IComparable<T>接口,那么该数据在比较时会自动调用该数据类的比较方法进行比较,如果未继承该接口,就需要在输入时指定该数据类型使用哪种数据进行比较,如下文代码中,我们使用了d.age属性进行数据比较。
  • 方式二:使用封装好的方法OrderBy(),该方法使用比较简单,可以直接调用对应的方法即可,注意事项跟使用原生的LINQ语句一致。
static void test_person_linq()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);// 1. 方式一IEnumerable<Person> query = from d in listorderby d.ageselect d;// 2. 方式二query = list.OrderBy(x => x.age);print_array(query);
}

如果想进行逆序排序,只需要添加descending关键字进行设定,或者直接使用OrderByDescending() 方法。

static void test_person_linq_()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);// 1. 方式一IEnumerable<Person> query = from d in listorderby d.age descendingselect d;// 2. 方式二query = list.OrderByDescending(x => x.age);print_array(query);
}

3. 多条件排序

  在实际使用时,我们可能会遇到多条件排序,即第一个条件相等时时,在采用第二个条件排序,如果遇到这种情况,我们处理起来可能就比较麻烦,对于自定义数据,如果我们在定义数据时继承IComparable<T>接口,并在接口方法中自定义排序要求即可。在下面中我们提供了一种使用Sort()接口并利用委托函数定义比较规则来实现数据排序,代码如下所示:

static void test_person_sort_more()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);list.Sort((x, y) => {if (x.age > y.age) { return 1; }else if (x.age == y.age){if (x.id > y.id) { return 1; }else { return -1; }}else { return -1; }});print_array(list);}

  如果想进行逆序排序,只需要修改一下相关的比较条件即可,逆序排序代码如下所示:

static void test_person_sort_more_()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);list.Sort((x, y) => {if (y.age > x.age) { return 1; }else if (y.age == x.age){if (y.id > x.id) { return 1; }else { return -1; }}else { return -1; }});print_array(list);
}

  通过上面代码我们可以看出使用除了可以使用Sort()接口是比较复杂的,其中的比较过程需要我们自己定义。下面我们将介绍使用LINQ语言进行多条件排序,当我们使用原生的LINQ语句时,在进行自定义数据比较时,需要声明所选择的对象的属性,并且按照先后顺序进行排序即可;如果使用封装后的LINQ语句,可以使用OrderBy()以及ThenBy()分别指定条件,在添加条件时,要生命比较的对象属性。代码如下所示:

static void test_person_linq_more()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);// 1. 方式一IEnumerable<Person> query = from d in listorderby d.age, d.idselect d;// 2. 方式二query = list.OrderBy(x => x.age).ThenBy(x => x.id);print_array(query);
}

  如果想进行逆序排序,对于原生LINQ语句,在条件后添加descending即可,对于封装后的LINQ语句,

static void test_person_linq_more_()
{List<Person> list = new List<Person>(){new Person(){name="a",age=15,id=1 },new Person(){name="b",age=12,id=2 },new Person(){name="c",age=14,id=3 },new Person(){name="d",age=12,id=4 },new Person(){name="e",age=14,id=5 },new Person(){name="f",age=12,id=6 },new Person(){name="g",age=15,id=7 },};print_array(list);// 1. 方式一IEnumerable<Person> query = from d in listorderby d.age descending, d.id descendingselect d;// 2. 方式二query = list.OrderByDescending(x => x.age).ThenByDescending(x => x.id);print_array(query);
}

  自定义数据排序后,程序运行最后输出为:

在这里插入图片描述

  自定义数据逆序排序后,程序运行最后输出为:
在这里插入图片描述

4. 多维数据排序

  在实际应用中,我们可能还会使用到多维数据,例如对于二维数据,我们在排序时可能会按照第二维数据的第一个数据作为主要排序关键字,第二数据作为第二个关键字进行排序,当遇到这种情况时,我们可以直接使用LINQ语句进行排序,如下面代码所示,我们定义了一个二维数组,类似于将一系列点数据存放到数组中,然后我们可以参考上文中自定义数据排序方法,书写排序代码:

static void test_array_sort()
{List<List<int>> list = new List<List<int>>() {new List<int>{ 1, 9 } ,new List<int>{ 6, 6 } ,new List<int>{ 1, 4 } ,new List<int>{ 6, 2 } ,new List<int>{ 1, 6 } ,new List<int>{ 7, 2 } ,new List<int>{ 1, 2 } ,new List<int>{ 3, 5 }};print_array(list);// 1. 方式一IEnumerable<List<int>> query = from d in listorderby d[0], d[1]select d;// 2. 方式二query = list.OrderBy(x => x[0]).ThenBy(x => x[1]);print_array(query);
}

排序后结果输出为:

在这里插入图片描述

5. 总结

以上就是给大家带来的自定义数据排序方法一些实现方式,希望大家在日常使用中能够用到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/589303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区分LR(0),SLR(1),LR(1)和LALR(1)

目录 对于LR(0)文法&#xff1a; 对于SLR(1)文法&#xff1a; 对于LR(0)和SLR(1)文法&#xff1a; 对于LR(1)和SLR(1)文法&#xff1a; 对于LALR(1)文法&#xff1a; 例题1&#xff1a; 例题2&#xff1a; 例题3&#xff1a; 例题4&#xff1a; 这几个文法大致的步骤都…

推荐几个贼有意思的开源项目!

这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、Java、Go、C/C、Swift...让你在短时间内感受到开源的魅力&#xff0c;对编程产生兴趣&#xff01; C 项目 1、kilo&#xff1a;不到 1 千行代码实现的迷你文本编辑器。该项…

STL容器——map

由于某些原因其实就是作者咕咕咕了 &#xff0c;这篇文章到2023年的最后一天才更出来 map的认识 关于map&#xff0c;这是一种常用的工具 基本上可以看成一个下标可以为任意的数组 注意&#xff0c;这里的任意&#xff0c;包括C中所有类型的所有取值可能 也就是说下标是什…

Portraiture4.1汉化版PS磨皮插件(支持原生m1芯片m2)

Portraiture汉化版PS磨皮插件。本期推荐一款全新ai算法ps2024中文汉化版ps磨皮插件Portraiture 4.1.2美颜滤镜安装包最新版ps调整肤色插件! 全新Portraiture 4.1.2版本PS人像修图美颜磨皮插件&#xff0c;升级AI算法&#xff0c;并支持多人及全身磨皮美化模式&#xff0c;推荐…

c++对c的加强

目录 提出了命名空间的概念 实用性增强 register关键字增强 变量检测增强 struct类型加强 C中所有的变量和函数都必须有类型 新增bool数据类型 提出了命名空间的概念 命名空间将全局作用域分成不同的部分 不同命名空间中的标识符可以同名而不会发生冲突 命名空间可以相互…

TypeScript 类方法装饰器

type ClassMethodDecorator (value: Function,context: {kind: method;name: string | symbol;static: boolean;private: boolean;access: { get: () > unknown };addInitializer(initializer: () > void): void;} ) > Function | void; 1、如果装饰器返回一个函数就…

C# 中 async/await 遇上 forEach 两种写法,是否按照遍历?

在 C# 中&#xff0c;async/await 与 forEach 可以搭配使用&#xff0c;但需要注意的是&#xff0c;forEach 本身不是一个异步操作&#xff0c;它会按顺序同步地遍历集合中的元素&#xff0c;并将每个元素作为参数传递给回调函数。因此&#xff0c;如果在 forEach 循环中使用 a…

【嵌入式开发 Linux 常用命令系列 7.3 -- linux 命令行数值计算】

文章目录 linux 命令行数值计算使用 awk使用 bc 命令使用 Bash 的内置算术扩展使用 expr脚本命令实现 linux 命令行数值计算 在 Linux 命令行中&#xff0c;您可以使用多种方法来执行基本的数学运算。以下是一些示例&#xff1a; 使用 awk awk 是一个强大的文本处理工具&…

【C#】知识点实践序列之Lock的输出多线程信息

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂之知识点实践序列》文章。 2023年第2篇文章&#xff0c;此篇文章是C#知识点实践序列之Lock知识点&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 本篇在Lock锁定代码…

CAN,SPI,IIC,USART每帧的组成

字节是计算机中用于存储数据的基本单位&#xff0c;一个字节由8个二进制位组成。在计算机科学中&#xff0c;字节的大小是固定的&#xff0c;即1字节8位。1比特1位 在不同的数据类型中&#xff0c;字节的大小也不同。例如&#xff0c;在ASCII码中&#xff0c;一个英文字母或数…

【python_数据分组】

对excel按照标签进行分组&#xff0c;例如按照“开票主体和对方公司”进行分组&#xff0c;并获取对应的明细。 表格如下&#xff1a; def main(excel_data):result {}for d in excel_data:if str(d[0])str(d[1]) in result:result[str(d[0])str(d[1])].append([d[0],d[1],…

Java 语法糖的介绍

在Java编程中&#xff0c;语法糖是一种简化代码的技巧&#xff0c;它可以使代码更易读、易写&#xff0c;同时提高开发效率。尽管从语法上看&#xff0c;它更像是一种装饰&#xff0c;但它能给我们的代码带来革命性的改变。 一、什么是Java语法糖&#xff1f; "语法糖&q…

删除重复字符

本题要求编写程序&#xff0c;将给定字符串去掉重复的字符后&#xff0c;按照字符ASCII码顺序从小到大排序后输出。 输入格式&#xff1a; 输入是一个以回车结束的非空字符串&#xff08;少于80个字符&#xff09;。 输出格式&#xff1a; 输出去重排序后的结果字符串。 输…

leetcode每日一题42

107.二叉树的层序遍历II 就层序遍历后reverse一下 class Solution { public:vector<vector<int>> levelOrderBottom(TreeNode* root) {queue<TreeNode*> que;if(root!nullptr)que.push(root);vector<vector<int>> result;while(!que.empty()){…

web component - 使用HTML Templates和Shadow DOM构建现代UI组件

Web Component是一种用于构建可重用的UI组件的技术。它使用标准化的浏览器API&#xff0c;包括Custom Elements、Shadow DOM和HTML Templates来实现组件化开发方式。这些API都是现代浏览器原生支持的&#xff0c;因此不需要引入第三方库或框架即可使用。 在这篇博客中&#xf…

[Verilog] 加法器(半加法器 | 全加法器 | 串行加法器 | 并行加法器 | 十进制加法器)详解

前言 在数字电路中,加法器是一种常见的逻辑电路,用于将两个数字相加。本文将介绍如何使用Verilog实现各种加法器。 1 加法器种类 整数加法器 半加器(Half Adder):它是最简单的加法器,只能进行两个输入位的相加操作,不包括进位位。全加器(Full Adder):它是最基本的加…

第6课 用window API捕获麦克风数据并加入队列备用

今天是2024年1月1日&#xff0c;新年的第一缕阳光已经普照大地&#xff0c;祝愿看到这篇文章的所有程序员或程序爱好者都能在新的一年里持之以恒&#xff0c;事业有成。 今天也是我加入CSDN的第4100天&#xff0c;但回过头看一看&#xff0c;这么长的时间也没有在CSDN写下几篇…

SpringCloud-高级篇(九)

&#xff08;1&#xff09;Seata高可用 我们学习了Seata的各种用法了&#xff0c;Seata的服务是单节点部署的&#xff0c;这个服务如果挂了&#xff0c;整个事务都没有办法完了&#xff0c;下面我们学习Seata的高可用的知识。 实现高可用&#xff0c;还是比较简单&#xff0c;…

UntiyShader(六)Unity提供的Cg/HLSL语义

目录 前言 一、什么是语义(Semantics) 系统数值语义(system-value semantics) 二、Unity

QT上位机开发(抽奖软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 用抽奖软件抽奖&#xff0c;是一种很常见的抽奖方式。特别是写这篇文章的时候&#xff0c;正好处于2023年12月31日&#xff0c;也是一年中最后一天…