2010-06-16 29 views
10

Có thể có câu lệnh foreach sẽ chuyển qua đối tượng Bộ sưu tập theo thứ tự ngược lại không?Làm thế nào bạn có thể đảo ngược việc lướt qua bộ sưu tập C#?

Nếu không phải là câu hỏi foreach, có cách nào khác không?

+3

co rúm tại các ý kiến ​​và câu trả lời trong chủ đề này. Đảo ngược() là * không * thay thế cho vòng lặp for(), nó có các yêu cầu lưu trữ O (n). Hộp đen LINQ có thể nguy hiểm. –

+0

@Hans: Sai. 'Đảo ngược' sẽ sử dụng' IList' nếu có. – SLaks

+1

@SLaks: ở đâu? Tôi không thấy nó. –

Trả lời

18

Bạn có thể sử dụng một for vòng bình thường ngược, như thế này:

for (int i = collection.Count - 1; i >= 0 ; i--) { 
    var current = collection[i]; 
    //Do things 
} 

Bạn cũng có thể sử dụng LINQ:

foreach(var current in collection.Reverse()) { 
    //Do things 
} 

Tuy nhiên, for vòng bình thường có lẽ sẽ nhanh hơn một chút.

+2

Vòng lặp 'for' có thể nhanh hơn, nhưng LINQ chắc chắn rõ ràng hơn. Do đó, tôi thích phiên bản LINQ hơn. – jball

+0

+1 cho phương thức tiện ích mà tôi đã quên! –

+0

Tôi không biết tại sao tôi không nhận ra bạn có thể đi qua một bộ sưu tập với các dấu ngoặc ... vì vậy tôi đoán chỉ của nó cho (int i = collections.Count; i> = 0; i -) ... Ugh Tôi là một moron. Cảm ơn. –

4

Nếu bạn đang sử dụng 3,5, có vẻ như có phương thức Reverse() trong LINQ Điều đó sẽ không lặp lại theo thứ tự ngược lại, nhưng sẽ đảo ngược toàn bộ danh sách, sau đó bạn có thể làm việc foreach.

Hoặc bạn có thể sử dụng một đơn giản cho tuyên bố:

for(int i = list.Count -1; i >= 0; --i) 
{ 
    x = list[i]; 
} 
+4

Bạn đang yêu cầu một lỗi 'IndexOutOfBounds'. Bắt đầu tại 'i = count - 1' – Greg

+2

" Điều đó sẽ không lặp lại theo thứ tự ngược lại, nhưng sẽ đảo ngược toàn bộ danh sách. " Điều này là không đúng sự thật. Lặp lại theo thứ tự ngược lại là * chính xác * phương thức mở rộng 'Enumerable.Reverse '. Bạn có thể đang nghĩ đến 'Danh sách .Reverse', mà [gây nhầm lẫn có cùng tên] (http://stackoverflow.com/questions/2828917/most-awkward-misleading-method-in-the-net-api/2829051 # 2829051). –

+0

@Greg, bắt tốt, cập nhật. @Dan Tao, tôi đã nghĩ đến Danh sách .Reverse. – taylonr

6

Bạn chỉ có thể gọi Reverse() vào bộ sưu tập.

foreach(var item in collection.Reverse()) { ... } 
+0

Tôi không tin rằng có một Reverse() trên Bộ sưu tập đó là suy nghĩ đầu tiên của tôi. –

+2

@Sam F: Đó là [phương pháp mở rộng] (http://msdn.microsoft.com/en-us/library/bb383977.aspx) trên bất kỳ 'IEnumerable 'nào (bao gồm' Bộ sưu tập '), có sẵn từ. NET 3.5 trở đi. Xem [tại đây] (http://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods.aspx) để biết danh sách tất cả chúng. Nếu bạn đang sử dụng .NET 3.5 hoặc mới hơn, bạn chỉ cần thêm 'using System.Linq;' vào đầu tệp của bạn. –

+2

Tôi cho rằng tôi nên thêm ghi chú - gây nhầm lẫn đủ, Đảo ngược() có nghĩa khác với IList so với chú thích cho tiêu chuẩn IEnumerable . IList .Reverse() trả về khoảng trống để đoạn mã của tôi hoạt động, bạn phải nói collection.AsEnumerable(). Reverse(). Kinh doanh khó hiểu, đó. – 48klocs

3

Hoặc, nếu bộ sưu tập là IEnumerable và do đó không có quyền truy cập ngẫu nhiên, hãy sử dụng phương pháp IEnumerable.Reverse() của System.Linq và áp dụng tìm kiếm như bình thường.

using System.Linq; 

foreach (var c in collection.Reverse()) { 
} 
+0

Đảo ngược là tùy chọn * khả thi * duy nhất để đảo ngược lặp lại trên một bộ sưu tập. Quá nhiều bộ sưu tập không thể lập chỉ mục được. – Randolpho

2
 List<string> items = new List<string> 
     { 
      "item 1", 
      "item 2", 
      "item 3", 
      "item 4", 
     }; 
     lines.AsEnumerable().Reverse() 
          .Do(a => Console.WriteLine(a), ex => Console.WriteLine(ex.Message),() => Console.WriteLine("Completed")) 
          .Run();   

Reactive Extension for .NET 3.5/4.0

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