2013-05-22 30 views
6

Tôi có một danh sách các đối tượng có Xếp hạng thuộc tính. Đây là một số nguyên.Làm thế nào tôi có thể sắp xếp nhưng đặt số không ở dưới cùng?

Tôi muốn sắp xếp theo cấp bậc trên quan điểm của tôi nhưng khi tôi làm điều này:

myObjects = myObjects.Orderby(r=>r.Rank); 

tôi nhận được tất cả các số không (có nghĩa là những chưa được thiết lập ở đầu trang)

Tôi muốn để đặt hàng 1 -> n nhưng có số 0 ở cuối danh sách.

Tôi muốn nó được như hiệu quả một loại càng tốt như danh sách khá dài

Trả lời

18

LINQ:

myObjects = myObjects 
    .OrderBy(r => r.Rank == 0) //false before true 
    .ThenBy(r => r.Rank); 

này sẽ không thực sự làm hai loại đầy đủ. Nó sẽ kết hợp hai lambdas thành đơn sắp xếp từ điển trên hai khóa.

Nếu bạn không thoải mái với không quá rõ ràng false -before- true quy tắc, bạn có thể thay thế lambda đầu tiên với r => r.Rank == 0 ? 1 : 0 - nhưng, biết quy tắc false -before- true làm cho điều này dường như thực sự không cần thiết.

+0

có cách nào tốt hơn mà không phải làm hai loại đầy đủ không? – leora

+0

@leora: Xem http://msmvps.com/blogs/jon_skeet/archive/2011/01/04/reimplementing-linq-to-objects-part-26a-iorderedenumerable.aspx (và các bài đăng tiếp theo) để biết thêm chi tiết –

+2

@leora: Điều này không làm hai loại đầy đủ. "OrderBy/ThenBy" khá thông minh. Hãy nhớ rằng, kết quả của biểu thức truy vấn là * truy vấn *, không * tính toán kết quả của truy vấn *. Khi truy vấn được thực hiện, truy vấn biết liệu có một ThenBy sau OrderBy hay không. –

6

Bạn có thể tạo trình so sánh tùy chỉnh (triển khai IComparer) và sắp xếp các số 0 ở dưới cùng. Mã giả sẽ là:

public class ZeroComparer : IComparer { 
    public int Compare(Object intA, Object intB) { 
     if(intA == 0 && intB != 0) 
      return -1; 
     if(intA != 0 && intB == 0) 
      return 1; 
     return int.Compare(intA, intB); 
    } 
} 

Sau đó, sử dụng nó như:

var comparer = new ZeroComparer(); 
myObjects = myObjects.Orderby(r=>r.Rank, comparer); 

Một ví dụ nhanh về cách sử dụng Người đối chiếu tùy chỉnh:

Use own IComparer<T> with Linq OrderBy

1
myObjects = myObjects.Orderby(r => r.Rank == 0 ? int.MaxValue : r.Rank); 

để đối phó với trường hợp Rank == int.MaxValue:

myObjects = myObjects.Orderby(r => r.Rank == 0 ? int.MaxValue : r.Rank - 1); 
+1

Điều gì xảy ra nếu 'int.MaxValue' là giá trị hợp lệ cho 'Xếp hạng'? – svick

+1

Nhận xét tốt, vì vậy chúng ta cần phải lấy '1' để xếp hạng trong mệnh đề thứ tự. Câu hỏi chỉnh sửa hạt giống. – polkduran

Các vấn đề liên quan