C#中List<>的排序相关的使用方法
list的排序一般使用Sort和LINQ的Orderby方法,本文主要介绍其如何使用。
🌮1.Sort和实现Comparable接口
此方式需要类去实现IComparable接口
public class OrderTest
{
[Test]
public void OraderTest()
{
List<ExpOne> list = new List<ExpOne>()
{
new ExpOne(){ NumOne = 3.12M, NumTwo = 5.54M, NumThree = 4.22M},
new ExpOne(){ NumOne = 6.76M, NumTwo = 3.54M, NumThree = 7.67M},
new ExpOne(){NumOne = 1.23M, NumTwo = 7.32M, NumThree = 2.85M},
new ExpOne(){NumOne = 2.44M, NumTwo = 1.66M,NumThree = 6.11M}
};
list.Sort();
list.ForEach(item => { Console.WriteLine("值1为:"+item.NumOne+" 值2为:"+item.NumTwo +" 值3为:"+item.NumThree); });
}
/// <summary>
/// 用例类1
/// </summary>
public class ExpOne:IComparable
{
/// <summary>
/// 值一
/// </summary>
public decimal NumOne { get; set; }
/// <summary>
/// 值二
/// </summary>
public decimal NumTwo { get; set; }
/// <summary>
/// 值三
/// </summary>
public decimal NumThree { get; set; }
/// <summary>
/// 文本内容
/// </summary>
public string context { get; set; }
//重写比较方法
public int CompareTo(object obj)
{
ExpOne item = (ExpOne)obj;
//这里以属性NumTwo进行排序,返回正值为this对象大于OBJ
//返回负值为this对象小于OBJ
if (this.NumTwo >= item.NumTwo)
return 1;
else
return -1;
}
}
}
PS:Sort默认按Comparable的正值排序(也就是从小到大)
另外也可以不实现Comparable接口而传入一个匿名实现
[Test]
public void OraderTest()
{
List<ExpOne> list = new List<ExpOne>()
{
new ExpOne(){ NumOne = 3.12M, NumTwo = 5.54M, NumThree = 4.22M},
new ExpOne(){ NumOne = 6.76M, NumTwo = 3.54M, NumThree = 7.67M},
new ExpOne(){NumOne = 1.23M, NumTwo = 7.32M, NumThree = 2.85M},
new ExpOne(){NumOne = 2.44M, NumTwo = 1.66M,NumThree = 6.11M}
};
list.Sort((left,right)=>{
if (left.NumTwo >= right.NumTwo)
return 1;
else
return -1;
});
list.ForEach(item => { Console.WriteLine("值1为:"+item.NumOne+" 值2为:"+item.NumTwo +" 值3为:"+item.NumThree); });
}
/// <summary>
/// 用例类1
/// </summary>
public class ExpOne
{
/// <summary>
/// 值一
/// </summary>
public decimal NumOne { get; set; }
/// <summary>
/// 值二
/// </summary>
public decimal NumTwo { get; set; }
/// <summary>
/// 值三
/// </summary>
public decimal NumThree { get; set; }
/// <summary>
/// 文本内容
/// </summary>
public string context { get; set; }
}
}
效果也是一样的:
ps:Sort方法可以只对list一部分进行排序
🏀🐔2.使用LINQ进行排序
LINQ排序只需要使用OrderBy即可,功能也更加强大,同时也有几个需要注意的点。
🎤一.基础使用
public void OraderTest()
{
List<ExpOne> list = new List<ExpOne>()
{
new ExpOne(){ NumOne = 3.12M, NumTwo = 5.54M, NumThree = 4.22M, context = "2023/06/14 09:08:02"},
new ExpOne(){ NumOne = 6.76M, NumTwo = 3.54M, NumThree = 7.67M, context = "2023/06/14 08:46:02"},
new ExpOne(){NumOne = 1.23M, NumTwo = 7.32M, NumThree = 2.85M, context = "2023/06/14 10:02:45"},
new ExpOne(){NumOne = 2.44M, NumTwo = 1.66M,NumThree = 6.11M, context = "2023/06/14 08:39:34"}
};
list = list.OrderBy(it=>it.NumTwo).ToList(); //根据属性值排序
list = list.OrderBy(it => Convert.ToDateTime(it.context)).ToList(); //更具转化的属性值排序
list = list.OrderBy(it => it.NumOne).ThenBy(it => it.NumTwo).ToList(); //多个条件组合排序
list = list.OrderByDescending(it => it.NumTwo).ToList();
list = list.OrderByDescending(it => Convert.ToDateTime(it.context)).ToList();
list = list.OrderByDescending(it => it.NumOne).ThenBy(it => it.NumTwo).ToList();
list.ForEach(item => { Console.WriteLine("值1为:"+item.NumOne+" 值2为:"+item.NumTwo +" 值3为:"+item.NumThree); });
}
PS:
注意一定要排序后赋值给原list,不然对原list没有效果。
注意一定要排序后赋值给原list,不然对原list没有效果。
注意一定要排序后赋值给原list,不然对原list没有效果。
🏃二.进阶使用
指定排序顺序到特定值。
有时候我们希望某个值为特定值时,将其放到特殊的位置。(毕竟特殊值不像可用于排序的基础数据类型,可以直接用于排序,像是0,1,2,3…)
[Test]
public void OraderTest()
{
List<ExpOne> list = new List<ExpOne>()
{
new ExpOne(){ NumOne = 3.12M, NumTwo = 5.54M, NumThree = 4.22M, context = "艺演丁真"},
new ExpOne(){ NumOne = 6.76M, NumTwo = 3.54M, NumThree = 7.67M, context = "轶研丁真"},
new ExpOne(){NumOne = 1.23M, NumTwo = 7.32M, NumThree = 2.85M, context = "尼古丁真"},
new ExpOne(){NumOne = 2.44M, NumTwo = 1.66M,NumThree = 6.11M, context = "芙蓉王源"}
};
//这里为自定义的顺序,
List<string> MySortlist = new List<string>() { "尼古丁真","芙蓉王源","艺演丁真","轶研丁真" };
list = list.OrderBy(it => MySortlist.IndexOf(it.context)).ToList();
list.ForEach(item => { Console.WriteLine("值1为:"+item.NumOne+" 值2为:"+item.NumTwo +" 值3为:"+item.NumThree + " 名字是:"+item.context); });
}
/// <summary>
/// 用例类1
/// </summary>
public class ExpOne
{
/// <summary>
/// 值一
/// </summary>
public decimal NumOne { get; set; }
/// <summary>
/// 值二
/// </summary>
public decimal NumTwo { get; set; }
/// <summary>
/// 值三
/// </summary>
public decimal NumThree { get; set; }
/// <summary>
/// 文本内容
/// </summary>
public string context { get; set; }
}
}
PS:这个顺序集合可以是从别的数据库中读取,或是别的对象中获取。重点是;你可以完全控制每个元素的位置,自定义排序规则
复杂对象的自定义排序
有些集合的Model可能有别的引用类属性,如果需要按照其进行排序可能需要自定义其规则。(需要根据具体业务来确定)
例:
public class OrderTest
{
[Test]
public void OraderTest()
{
List<ExpOne> list = new List<ExpOne>()
{
new ExpOne(){ NumOne = 3.12M, NumTwo = 5.54M, NumThree = 4.22M, context = "艺演丁真", info = new InnerOne(){ Peopel_Age = 33 } },
new ExpOne(){ NumOne = 6.76M, NumTwo = 3.54M, NumThree = 7.67M, context = "轶研丁真", info = new InnerOne(){ Peopel_Age = 24 }} ,
new ExpOne(){NumOne = 1.23M, NumTwo = 7.32M, NumThree = 2.85M, context = "尼古丁真", info = new InnerOne(){ Peopel_Age = 28 }},
new ExpOne(){NumOne = 2.44M, NumTwo = 1.66M,NumThree = 6.11M, context = "芙蓉王源", info = new InnerOne(){ Peopel_Age = 19 }}
};
list = list.OrderBy(it => it.info,new CustomerComparer()).ToList();
list.ForEach(item => { Console.WriteLine("值1为:"+item.NumOne+" 值2为:"+item.NumTwo +" 值3为:"+item.NumThree + " 名字是:"+item.context +" 年龄为:"+item.info.Peopel_Age); });
}
/// <summary>
/// 用例类1
/// </summary>
public class ExpOne
{
/// <summary>
/// 值一
/// </summary>
public decimal NumOne { get; set; }
/// <summary>
/// 值二
/// </summary>
public decimal NumTwo { get; set; }
/// <summary>
/// 值三
/// </summary>
public decimal NumThree { get; set; }
/// <summary>
/// 文本内容
/// </summary>
public string context { get; set; }
public InnerOne info { get; set; }
}
public class InnerOne
{
public int Peopel_Age { get; set; }
}
/// <summary>
///
/// </summary>
public class CustomerComparer : Comparer<InnerOne>
{
public override int Compare([AllowNull] InnerOne x, [AllowNull] InnerOne y)
{
if (x.Peopel_Age >= y.Peopel_Age)
return 1;
else
return -1;
}
}
}