C#List<T>排序多权重、自定义
程序员文章站
2022-07-12 08:03:51
...
一、对基础类型排序
初始化一个list:
List<int> list = new List<int>() { 1, 3, 2, 8, 6 };
方法一:调用sort方法,如果需要降序,进行反转:
list.Sort();// 升序排序
list.Reverse();// 反转顺序
方法二:使用lambda表达式,在前面加个负号就是降序了
list.Sort((x, y) => x.CompareTo(y));//升序
list.Sort((x, y) => -x.CompareTo(y));//降序
二、对非基本类型排序,以一个类为例。
准备:
写一个bookcase类用于排序,里面有三个属性,一个键值集合,重写了ToString方法并且实现IComparable接口
public class bookcase : IComparable<bookcase>
{
Dictionary<string, int> BT = new Dictionary<string, int>() { { "书橱五", 5 }, { "书橱七", 7 }, { "书橱四", 4 }, { "书橱二", 2 }, { "书橱一", 1 }, { "书橱三", 3 }, { "书橱六", 6 } };
public int ID { get; set; }
public string name { get; set; }
/// <summary>
/// books
/// </summary>
public List<book> books { get; set; }
//重写了CompareTo方法,当书橱名相同时按ID排序
public int CompareTo(bookcase bk)
{
if (null == bk)
{
return 1;//空值比较大,返回1
}
//等于返回0
int re = BT[this.name].CompareTo(BT[bk.name]);
if (0 == re)
{
//Name相同再比较id
return this.ID.CompareTo(bk.ID);
}
return re;
}
//重写ToString
public override string ToString()
{
return "ID:" + this.ID + " Name:" + this.name;
}
}
/// <summary>
/// book类
/// </summary>
public class book
{
public string id { get; set; }
//书橱id
public string bookcase_bid { get; set; }
public string bookName { get; set; }
}
添加模拟数据:
//书橱(主表)
List<bookcase> ls_f = new List<bookcase>();
//书本(从表)
List<book> books = new List<book>();
//添加模拟数据
book bk1 = new book() { id = "1", bookcase_bid = "1", bookName = "语文" };
book bk2 = new book() { id = "2", bookcase_bid = "1", bookName = "数学" };
book bk3 = new book() { id = "3", bookcase_bid = "2", bookName = "英语" };
book bk4 = new book() { id = "4", bookcase_bid = "2", bookName = "历史" };
books.Add(bk1);
books.Add(bk2);
books.Add(bk3);
books.Add(bk4);
bookcase bkcase1 = new bookcase() { ID = 1, name = "书橱三", books = books };
bookcase bkcase2 = new bookcase() { ID = 2, name = "书橱一", books = books };
bookcase bkcase3 = new bookcase() { ID = 4, name = "书橱六", books = books };
bookcase bkcase4 = new bookcase() { ID = 3, name = "书橱六", books = books };
ls_f.Add(bkcase1);
ls_f.Add(bkcase2);
ls_f.Add(bkcase3);
ls_f.Add(bkcase4);
初始化一个键值集合用来自定义书橱名排序:
Dictionary<string, int> BT = new Dictionary<string, int>() { { "书橱五", 5 }, { "书橱七", 7 }, { "书橱四", 4 }, { "书橱二", 2 }, { "书橱一", 1 }, { "书橱三", 3 }, { "书橱六", 6 } };
实现IComparable接口
这时无参的Sort()方法已经不可用了,因为不知道如何排序了,这时就需要借助IComparable接口 重写的CompareTo方法(已写在之前准备的类中)
ls_f.Sort();
实现IComparer接口
写一个比较容器类继承IComparer接口
//比较器类 实现IComparer接口
public class ComparerName : IComparer<bookcase>
{
Dictionary<string, int> BT = new Dictionary<string, int>() { { "书橱五",5 }, { "书橱七",7 }, { "书橱四",4 }, { "书橱二",2 }, { "书橱一",1 }, {"书橱三",3 }, { "书橱六",6 } };
//当书橱名相同时按ID排序
public int Compare(bookcase x, bookcase y)
{
int re = BT[x.name].CompareTo(BT[y.name]);
if (0 == re)
{
return x.ID.CompareTo(y.ID);
}
return re;
}
}
程序调用:ls_f.Sort(new ComparerName());
使用委托或lambda表达式来排序:
虽然想实现排序上面的接口代码也不多,但有时候只是偶尔排序,并不想修改类,怎么办呢?当然有更简单的方法,委托和lambda表达式:
用委托构造重载:
ls_f.Sort(
delegate(bookcase b1, bookcase b2)
{
int re = BT[b1.name].CompareTo(BT[b2.name]);
if (0 == re)
{
return b1.ID.CompareTo(b2.ID);
}
return re;
}
);
使用lambda表达式来排序:
ls_f.Sort((x, y) =>
{
int re = BT[x.name].CompareTo(BT[y.name]);
if (0 == re)
{
return x.ID.CompareTo(y.ID);
}
return re;
});
通过Linq语法进行排序,按书橱名:
var query = from x in ls_f
orderby BT[x.name]
select x;
ls_f = query.ToList();
OrderBy方法:此方法将排序好的list再赋给原来的list,也可以给其他的。
ls_f = ls_f.OrderBy(o => BT[o.name]).ThenBy(o => o.ID).ToList();//升序
ls_f = ls_f.OrderByDescending(o => BT[o.name]).ThenByDescending(o => o.ID).ToList();//降序
上一篇: init进程解析init.rc文件流程