Shy*_*yju 1146 c# sorting generics list
我有一个名为类Order具有如属性OrderId,OrderDate,Quantity,和Total.我有这个Order类的列表:
List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders
Run Code Online (Sandbox Code Playgroud)
现在我想根据Order对象的一个属性对列表进行排序,例如我需要按订单日期或订单ID对其进行排序.
我怎样才能在C#中做到这一点?
Laz*_*rus 1668
我能想到的最简单的方法是使用Linq:
List<Order> SortedList = objListOrder.OrderBy(o=>o.OrderDate).ToList();
Run Code Online (Sandbox Code Playgroud)
Luk*_*keH 708
如果您需要就地对列表进行排序,那么您可以使用该Sort方法,传递Comparison<T>委托:
objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));
Run Code Online (Sandbox Code Playgroud)
如果您希望创建一个新的排序序列而不是就地排序,那么您可以使用LINQ的OrderBy方法,如其他答案中所述.
djd*_*d87 211
要在.Net2.0上没有LINQ的情况下执行此操作:
List<Order> objListOrder = GetOrderList();
objListOrder.Sort(
delegate(Order p1, Order p2)
{
return p1.OrderDate.CompareTo(p2.OrderDate);
}
);
Run Code Online (Sandbox Code Playgroud)
如果您使用的是.Net3.0,那么LukeH的答案就是您所追求的.
要对多个属性进行排序,您仍然可以在委托中执行此操作.例如:
orderList.Sort(
delegate(Order p1, Order p2)
{
int compareDate = p1.Date.CompareTo(p2.Date);
if (compareDate == 0)
{
return p2.OrderID.CompareTo(p1.OrderID);
}
return compareDate;
}
);
Run Code Online (Sandbox Code Playgroud)
这将为您提供降序 orderIds的升序日期.
但是,我不建议坚持代表,因为这意味着很多地方没有代码重用.您应该实现一个IComparer并将其传递给您的Sort方法.看到这里.
public class MyOrderingClass : IComparer<Order>
{
public int Compare(Order x, Order y)
{
int compareDate = x.Date.CompareTo(y.Date);
if (compareDate == 0)
{
return x.OrderID.CompareTo(y.OrderID);
}
return compareDate;
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用这个IComparer类,只需实例化它并将其传递给Sort方法:
IComparer<Order> comparer = new MyOrderingClass();
orderList.Sort(comparer);
Run Code Online (Sandbox Code Playgroud)
PSK*_*PSK 102
订购列表的最简单方法是使用 OrderBy
List<Order> objListOrder =
source.OrderBy(order => order.OrderDate).ToList();
Run Code Online (Sandbox Code Playgroud)
如果您想按照SQL Query之类的多个列进行排序.
ORDER BY OrderDate, OrderId
Run Code Online (Sandbox Code Playgroud)
为此,您可以使用ThenBy以下内容.
List<Order> objListOrder =
source.OrderBy(order => order.OrderDate).ThenBy(order => order.OrderId).ToList();
Run Code Online (Sandbox Code Playgroud)
Jim*_*ffa 32
没有Linq就像你说的那样做:
public class Order : IComparable
{
public DateTime OrderDate { get; set; }
public int OrderId { get; set; }
public int CompareTo(object obj)
{
Order orderToCompare = obj as Order;
if (orderToCompare.OrderDate < OrderDate || orderToCompare.OrderId < OrderId)
{
return 1;
}
if (orderToCompare.OrderDate > OrderDate || orderToCompare.OrderId > OrderId)
{
return -1;
}
// The orders are equivalent.
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的订单列表上调用.sort()
rad*_*bob 24
一种经典的面向对象解决方案
首先,我必须接受LINQ的精彩内容......现在我们已经把它排除在外了
JimmyHoffa答案的一个变种.使用泛型,CompareTo参数变为类型安全.
public class Order : IComparable<Order> {
public int CompareTo( Order that ) {
if ( that == null ) return 1;
if ( this.OrderDate > that.OrderDate) return 1;
if ( this.OrderDate < that.OrderDate) return -1;
return 0;
}
}
// in the client code
// assume myOrders is a populated List<Order>
myOrders.Sort();
Run Code Online (Sandbox Code Playgroud)
当然,此默认可排序性是可重用的.也就是说,每个客户端都不必冗余地重写排序逻辑.交换"1"和"-1"(或逻辑运算符,您的选择)会反转排序顺序.
rog*_*ger 18
//用于gridview的完全通用排序
public List<T> Sort_List<T>(string sortDirection, string sortExpression, List<T> data)
{
List<T> data_sorted = new List<T>();
if (sortDirection == "Ascending")
{
data_sorted = (from n in data
orderby GetDynamicSortProperty(n, sortExpression) ascending
select n).ToList();
}
else if (sortDirection == "Descending")
{
data_sorted = (from n in data
orderby GetDynamicSortProperty(n, sortExpression) descending
select n).ToList();
}
return data_sorted;
}
public object GetDynamicSortProperty(object item, string propName)
{
//Use reflection to get order type
return item.GetType().GetProperty(propName).GetValue(item, null);
}
Run Code Online (Sandbox Code Playgroud)
任何使用可空类型的人Value都需要使用CompareTo.
objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));
Run Code Online (Sandbox Code Playgroud)
使用 LINQ
objListOrder = GetOrderList()
.OrderBy(o => o.OrderDate)
.ToList();
objListOrder = GetOrderList()
.OrderBy(o => o.OrderId)
.ToList();
Run Code Online (Sandbox Code Playgroud)
这是一个通用的LINQ扩展方法,它不会创建列表的额外副本:
public static void Sort<T,U>(this List<T> list, Func<T, U> expression)
where U : IComparable<U>
{
list.Sort((x, y) => expression.Invoke(x).CompareTo(expression.Invoke(y)));
}
Run Code Online (Sandbox Code Playgroud)
要使用它:
myList.Sort(x=> x.myProperty);
Run Code Online (Sandbox Code Playgroud)
我最近构建了另外一个接受一个ICompare<U>,以便您可以自定义比较.当我需要进行自然字符串排序时,这会派上用场:
public static void Sort<T, U>(this List<T> list, Func<T, U> expression, IComparer<U> comparer)
where U : IComparable<U>
{
list.Sort((x, y) => comparer.Compare(expression.Invoke(x), expression.Invoke(y)));
}
Run Code Online (Sandbox Code Playgroud)
小智 5
请让我用一些示例代码来完成@LukeH 的答案,因为我已经测试过它,我相信它可能对某些人有用:
public class Order
{
public string OrderId { get; set; }
public DateTime OrderDate { get; set; }
public int Quantity { get; set; }
public int Total { get; set; }
public Order(string orderId, DateTime orderDate, int quantity, int total)
{
OrderId = orderId;
OrderDate = orderDate;
Quantity = quantity;
Total = total;
}
}
public void SampleDataAndTest()
{
List<Order> objListOrder = new List<Order>();
objListOrder.Add(new Order("tu me paulo ", Convert.ToDateTime("01/06/2016"), 1, 44));
objListOrder.Add(new Order("ante laudabas", Convert.ToDateTime("02/05/2016"), 2, 55));
objListOrder.Add(new Order("ad ordinem ", Convert.ToDateTime("03/04/2016"), 5, 66));
objListOrder.Add(new Order("collocationem ", Convert.ToDateTime("04/03/2016"), 9, 77));
objListOrder.Add(new Order("que rerum ac ", Convert.ToDateTime("05/02/2016"), 10, 65));
objListOrder.Add(new Order("locorum ; cuius", Convert.ToDateTime("06/01/2016"), 1, 343));
Console.WriteLine("Sort the list by date ascending:");
objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));
foreach (Order o in objListOrder)
Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);
Console.WriteLine("Sort the list by date descending:");
objListOrder.Sort((x, y) => y.OrderDate.CompareTo(x.OrderDate));
foreach (Order o in objListOrder)
Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);
Console.WriteLine("Sort the list by OrderId ascending:");
objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));
foreach (Order o in objListOrder)
Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);
//etc ...
}
Run Code Online (Sandbox Code Playgroud)