前言

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


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

1. 常规数据排序

1.1 使用Sort排序

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

  • 方式一:使用默认的Sort()方法直接就可以进行排序。
  • 方式二:使用Sort()方法并添加回调函数,回调函数调用数据类型CompareTo()方法。
  • 方式三:使用Sort()方法并添加回调函数,回调函数进行自定义,此处采用三目运算符写了个简单的方法。
static void test_general_sort()
{
int[] data = { 89, 63, 48, 62, 75, 663, 45, 359, 42 };
// 1. 方式一
Array.Sort(data);
// 2. 方式二
Array.Sort(data, (x, y) => x.CompareTo(y));
// 3. 方式三
Array.Sort(data, (x, y) => x > y ? 1 : -1);
print_array(data);
}

  如果是想进行逆序排序,最简单的方式就是将正序排列的数组进行一次反转即可,不然的话就是改变方法二以及方法三的回调函数输出,如下面代码所示。

static void test_general_sort_()
{
int[] data = { 89, 63, 48, 62, 75, 663, 45, 359, 42 };
// 1. 方式一
Array.Sort(data);
Array.Reverse(data);
// 2. 方式二
Array.Sort(data, (x, y) => y.CompareTo(x));
// 3. 方式三
Array.Sort(data, (x, y) => x > y ? -1 : 1);
print_array(data);
}

1.2 使用LINQ语句进行排序

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

  • 方式一:使用原生的LINQ语句进行查询,此处主要通过自己写LINQ语句;
  • 方式二:使用封装好的方法OrderBy(),该方法使用比较简单,可以直接调用对应大方法即可。
static void test_general_linq()
{
int[] data = { 89, 63, 48, 62, 75, 663, 45, 359, 42 };
// 1. 方式一
IEnumerable<int> query = from d in data
orderby d
select d;
// 2. 方式二
query = data.OrderBy(x => x);
print_array(query);
}

  如果要项进行逆序排序,此处可以添加descending关键字进行设定,或者直接使用OrderByDescending() 方法。

static void test_general_linq_()
{
int[] data = { 89, 63, 48, 62, 75, 663, 45, 359, 42 };
// 1. 方式一
IEnumerable<int> query = from d in data
orderby d descending
select d;
// 2. 方式二
query = data.OrderByDescending(x => x);
print_array(query);
}

1.3 多条件排序

  在实际使用时,我们可能会遇到多条件排序,即第一个条件相等时时,在采用第二个条件排序,如果遇到这种情况,我们处理起来可能就比较麻烦。如下面代码所示,对于一个字符串数组,我想首先按照字符串长度进行排序,如果字符串长度相等,就按照首字母进行排序。实现方式如下所示:

static void test_general_sort_more()
{
string[] words = { "the", "quick", "brown", "fox", "jumps", "and" };
Array.Sort<string>(words, (x, y) =>
{
if (x.Length > y.Length) { return 1; }
else if (x.Length == y.Length)
{
if (x.Substring(0, 1)[0] > y.Substring(0, 1)[0]) { return 1; }
else { return -1; }
}
else { return -1; }
});
print_array(words);
}

  在上面这段代码中,我们主要是使用了Lambda表达式创建了一个委托函数,在这个委托函数里,我们按照排序要求,对其进行了定义,主要是对返回值的条件进行了定义,最后排序结果输出为:

Array = {the, quick, brown, fox, jumps, and}
Array = {and, fox, the, brown, jumps, quick}

  不过该方式看起来实现是比较复杂的,对于大多是人来说,可能很难看懂,所以此处我们向大家展示一个比较简单的方式,就是使用LINQ语句进行多条件排序,如下面代码所示:

static void test_general_linq_more()
{
string[] words = { "the", "quick", "brown", "fox", "jumps", "and" };
// 1. 方式一
IEnumerable<string> query = from word in words
orderby word.Length, word.Substring(0, 1)
select word;
// 2. 方式二
query = words.OrderBy(x => x.Length).ThenBy(x => x.Substring(0, 1));
print_array(query);
}

  使用LINQ语句进行排序看起来就比较简单了,上面依旧是展示了两种方式,对于多条件排序,如果使用自定义LINQ语句排序就只需要在上一个条件后增加次要条件即可;如果使用封装后的LINQ语句,就可以在OrderBy()增加ThenBy()方法添加第二个条件。如果想实现反向排序,实现方式与上文相同。

2. 自定义数据排序

  下面我们进行自定义数据进行排序,如下面代码所示,我们在此处定义了一个 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 + ")";
}
};

2.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.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 list
orderby d.age
select 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 list
orderby d.age descending
select d;
// 2. 方式二
query = list.OrderByDescending(x => x.age);
print_array(query);
}

2.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 list
orderby d.age, d.id
select 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 list
orderby d.age descending, d.id descending
select d;
// 2. 方式二
query = list.OrderByDescending(x => x.age).ThenByDescending(x => x.id);
print_array(query);
}

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

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

3. 多维数据排序

  在实际应用中,我们可能还会使用到多维数据,例如对于二维数据,我们在排序时可能会按照第二维数据的第一个数据作为主要排序关键字,第二数据作为第二个关键字进行排序,当遇到这种情况时,我们可以直接使用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 list
orderby d[0], d[1]
select d;
// 2. 方式二
query = list.OrderBy(x => x[0]).ThenBy(x => x[1]);
print_array(query);
}

排序后结果输出为:

4. 总结

以上就是给大家带来的C#常用排序方式一些实现方式,希望大家在日常使用中能够用到。

【C# 技术】C# 常用排序方式的更多相关文章

  1. discuz 修改亮剑积分商城2.91模板(在常用设置中添加商场首页排序方式的背景颜色)

    在应用 -> 积分商城 -> 常用设置 中添加 商场首页排序方式 的背景颜色修改功能 步骤: 1.找到并打开此页面对应的模板source\plugin\aljsc\template\set ...

  2. 常用排序算法的python实现和性能分析

    常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...

  3. Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法

    Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...

  4. 转载部长一篇大作:常用排序算法之JavaScript实现

    转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...

  5. Java 常用排序算法/程序员必须掌握的 8大排序算法

    Java 常用排序算法/程序员必须掌握的 8大排序算法 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配 ...

  6. [MySQL] 字符集和排序方式

    字符串类型 MySQL的字符串分为两大类: 1)二进制字符串:即一串字节序列,对字节的解释不涉及字符集,因此它没有字符集和排序方式的概念 2)非二进制字符串:由字符构成的序列,字符集用来解释字符串的内 ...

  7. 常用排序算法java实现

    写在前面:纸上得来终觉浅.基本排序算法的思想,可能很多人都说的头头是到,但能说和能写出来,真的还是有很大区别的. 今天整理了一下各种常用排序算法,当然还不全,后面会继续补充.代码中可能有累赘或错误的地 ...

  8. 第四百一十五节,python常用排序算法学习

    第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...

  9. Java常用排序算法及性能测试集合

    测试报告: Array length: 20000 bubbleSort : 573 ms bubbleSortAdvanced : 596 ms bubbleSortAdvanced2 : 583 ...

  10. C++ STL 常用排序算法

    C++ STL 常用排序算法 merge() 以下是排序和通用算法:提供元素排序策略 merge: 合并两个有序序列,存放到另一个序列. 例如: vecIntA,vecIntB,vecIntC是用ve ...

随机推荐

  1. Java并发Map的面试指南:线程安全数据结构的奥秘

    简介 在计算机软件开发的世界里,多线程编程是一个重要且令人兴奋的领域.然而,与其引人入胜的潜力相伴而来的是复杂性和挑战,其中之一就是处理共享数据.当多个线程同时访问和修改共享数据时,很容易出现各种问题 ...

  2. 谱图论:Laplacian二次型和Markov转移算子

    以下部分是我学习CMU 15-751: TCS Toolkit的课堂笔记.由于只是个人笔记,因此许多地方在推导上可能不那么严谨,还望理论大佬多多包涵. 1 问题定义 1.1 无向图\(G\) 在本文中 ...

  3. 【Python进阶-PyQt5】00搭建PyQt5环境

    1.创建独立开发虚拟环境 1.1虚拟环境简介 我们编写的程序,有时用到的Python库是不一样的,比如说开发桌面应用程序我们主要用到PyQt5相关的Python库.开发Web应用程序我们主要用到Dja ...

  4. Python基础——变量、常量、数字类型、四 列表list、五 字典dict、六 布尔bool、垃圾回收机制、用户交互、运算符、流程控制

    文章目录 变量 一 引入 一.什么是变量? 二.为什么要有变量? 三.怎么使用变量(先定义.后使用) 3.1.变量的定义与使用 3.2.变量名的命名规范 3.3.变量名的命名风格 3.4.变量值的三大 ...

  5. 开发微信小程序技术栈

    开发微信小程序主要需要以下技术栈: 小程序框架参考文档 小程序组件参考文档 小程序 API 参考文档 小程序服务端 API 参考文档 微信开发者工具参考文档 微信云托管参考文档 微信云开发参考文档 1 ...

  6. EMC ndmp NAS

    NAS 是带存储系统的专用高性能文件服务器.它可提供文件级数据访问和共享. NAS 使用网络和文件共享协议,包括用于数据传输的 TCP/IP 以及用于远程文件服务的 CIFS 和 NFS. 最简单的备 ...

  7. 基于LangChain的LLM应用开发2——模型、提示和输出解析

    本次会讲解LangChain的三个基本组件:模型.提示和解析器. 名词解析 模型(Models):是指作为基础的大语言模型.LangChain中通过ChatOpenAI或者AzureChatOpenA ...

  8. Python 潮流周刊#24:no-GIL 提案正式被采纳了!

    你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中两则分享,不代表全部内容都是该主题,特此声明. 微信 | 博客 | 邮件 | Github | Tel ...

  9. P4156 [WC2016]论战捆竹竿 题解

    题目链接 题意描述 给定一个字符串 \(s\),你初始拥有一个空串 \(t\),每次可以选择这个字符串的一个 Border,去掉它后接在 \(t\) 的后面,操作后 \(s\) 不变,给出一个上限 \ ...

  10. 1.参考例5.2.1,设计一个序列检测器。功能是检测出串行输入数据Sin中的4位二进制序列0101(自左至右输入),当检测到该序列时,输入Out=1;没有检测到该序列时,输入Out=0。要求不考虑序列重叠,如010101的序列中只包含一个0101序列。

    设计块: module Detector2 ( input CP,Sin,nCR, output reg Out ); reg [1:0] Current_state,Next_state; para ...