2010-06-16 8 views
10

Ist es möglich, eine foreach Aussage zu haben, die durch ein Kollektion Objekt in umgekehrter Reihenfolge durchlaufen werden?Wie können Sie eine C# -Sammlung zurückverfolgen?

Wenn kein foreach Aussage, ist es eine andere Möglichkeit?

+3

auf die Kommentare und Antworten in diesem Thread kriechend. Reverse() ist * nicht * ein Ersatz für eine for() - Schleife, es hat O (n) Speicheranforderungen. Die LINQ-Blackbox kann gefährlich sein. –

+0

@Hans: Falsch. 'Reverse' verwendet' IList' falls verfügbar. – SLaks

+1

@SLaks: wo? Ich sehe es nicht. –

Antwort

18

Sie können eine normale for Schleife rückwärts verwenden, wie folgt aus:

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

Sie auch LINQ verwenden können:

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

jedoch die normale for Schleife wird wahrscheinlich ein wenig schneller sein.

+2

Die For-Schleife kann schneller sein, aber die LINQ ist sicherlich klarer. Ich würde daher die LINQ-Version bevorzugen. – jball

+0

+1 für eine Erweiterungsmethode, die ich vergessen habe! –

+0

Ich weiß nicht, warum ich nicht erkennen, Sie mit Klammern durch eine Sammlung ... durchqueren können, so dass ich denke, es ist nur for (int i = collections.Count; i> = 0; i -) ... Ugh, ich bin ein Idiot. Vielen Dank. –

4

Wenn Sie mit 3,5 arbeiten, sieht es so aus, als gäbe es in LINQ eine Reverse() -Methode Das wird nicht in umgekehrter Reihenfolge durchlaufen, aber würde die gesamte Liste umkehren, dann könnten Sie Ihre Foreach tun.

Oder Sie könnten eine einfache for-Anweisung verwenden:

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

Sie fragen nach einem 'IndexOutOfBounds' Fehler. Start bei 'i = count - 1' – Greg

+2

" Das wird nicht in umgekehrter Reihenfolge durchlaufen, sondern würde die gesamte Liste umkehren. " Das ist falsch. Das Iterieren in umgekehrter Reihenfolge ist * genau * was die Erweiterungsmethode "Enumerable.Reverse " tut. Vielleicht denken Sie an "Liste .Reverse", die [verwirrend den gleichen Namen] (http://stackoverflow.com/questions/2828917/most-awkward-misleading-method-in-the-net-api/2829051) # 2829051). –

+0

@Greg, guter Fang, aktualisiert. @Dan Tao, ich dachte an die Liste .Reverse. – taylonr

6

Sie haben soeben Reverse() auf die Sammlung nennen könnte.

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

Ich glaube nicht, dass es eine Reverse() auf Sammlungen , das war mein erster Gedanke. –

+2

@Sam F: Es ist eine [Erweiterungsmethode] (http://msdn.microsoft.com/en-us/library/bb383977.aspx) auf jedem 'IEnumerable ' (die 'Collection 'enthält), verfügbar von. Ab NET 3.5. Siehe [hier] (http://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods.aspx) für eine Liste von allen. Wenn Sie .NET 3.5 oder höher verwenden, müssen Sie lediglich "using System.Linq;" zum Anfang Ihrer Datei hinzufügen. –

+2

Ich nehme an, ich sollte eine Notiz hinzufügen - verwirrend genug, Reverse() hat eine andere Bedeutung für IList als es für Standard IEnumerable . IList .Reverse() gibt void zurück, damit mein Snippet funktioniert, müsste man collection.AsEnumerable() sagen. Reverse(). Verwirrendes Geschäft, das. – 48klocs

3

Alternativ, wenn die Sammlung ein IEnumerable ist und deshalb ohne Random Access verwenden System.Linq der IEnumerable.Reverse() -Methode und wenden forearch wie gewohnt.

using System.Linq; 

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

Reverse ist die einzige * praktikable * Option für die umgekehrte Iteration über eine Sammlung. Zu viele Sammlungen sind nicht indexierbar. – 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