![]() |
Delphi-Version: XE2
IEnumerable rückwärts durchlaufen
Meine Hausaufgaben habe ich nicht wirklich gemacht,
Delphi-Quellcode:
bzw.
IEnumerable
Delphi-Quellcode:
habe ich mir noch nicht wirklich im Detail angesehen.
IEnumerator
Ich habe beispielsweise eine generische Liste. Ich iteriere mit einem "for ... in" darüber. Ich möchte jetzt aber nicht "vorwärts" sondern "rückwärts" über die Liste rutschen. Wie macht der Profi das? Oder gibt es vielleicht einen Standard "Rückwärts"-Enumerator den ich irgendwie verwenden kann? Direkt (etwas unleserlich) anonym die drei IEnumerator-Methoden zu implementieren geht wahrscheinlich nicht und bläht den Code wohl zu sehr auf... |
AW: IEnumerable rückwärts durchlaufen
Das geht mit IEnumerable nicht.
MS hat das als nur nach vorne durchlaufbare Liste definiert. Siehe ![]() Aber was ist der Sinn davon das Rückwärts zu durchlaufen? |
AW: IEnumerable rückwärts durchlaufen
Du kannst die Liste vor der Verarbeitung "umdrehen".
|
AW: IEnumerable rückwärts durchlaufen
Die strikte Vorschrift von "vorwärts" lese ich auch aus der .NET-Doku jetzt nicht heraus. Wenn ich es auf die Schnelle richtig sehe, kann ich den Enumerator, den bsp. eine stinknormale TList zurückgibt, nicht zur Laufzeit ändern, oder? Sonst hätte ich mir ja für den Fall meinen eigenen "Spaß-Enumerator" basteln können...
Die Liste mit Reverse() umzudrehen ist eine gute Idee. Nur leider werkelt da keine Magie im Hintergrund, da wird ja physikalisch wirklich jeder Eintrag mit seinem Gegenstück vertauscht:
Delphi-Quellcode:
Meine Motivation war eigentlich aus Geschwindigkeitsgründen nicht ständig mit einem schrumpfenden Zahlen-Index in die Liste zu greifen sondern den Cursor des Enumerators zu nutzen. Ein Umdrehen der Liste ist zwar wirklich elegant, dauert aber wohl zu lange...
procedure TList<T>.Reverse;
var tmp: T; b, e: Integer; begin b := 0; e := Count - 1; while b < e do begin tmp := FItems[b]; FItems[b] := FItems[e]; FItems[e] := tmp; Inc(b); Dec(e); end; end; |
AW: IEnumerable rückwärts durchlaufen
Du könntest das auch in ein Objekt kapseln und eine revertete (wat'n Wort) "Schattenliste" mitführen. Die könntest Du dann entsprechend pflegen. Dafür dauert dann das Add länger ...
|
AW: IEnumerable rückwärts durchlaufen
Zitat:
Enumeriert man die Werte eines Dictionarys, kommen die in irgendeiner Reihenfolge. Dadurch macht auch das Umkehren der Reihenfolge keinen Sinn. Es gibt andere Interfaces, die auf definierte Reihenfolgen Rücksicht nehmen. |
AW: IEnumerable rückwärts durchlaufen
Ich habe "for .. in" schon immer mehr wie eine Collection verstanden. Also eine lose Ansammlung von gleichartigen Daten, die prinzipbedingt keiner Reihenfolge angehören. Wenn ich geordnete Listen nutze, bin ich daher immer beim "for i := 0 to MAX" geblieben, einfach weil es meinem Verständnis eher entsprach.
|
AW: IEnumerable rückwärts durchlaufen
Jetzt fing ich gerade an mich zu wundern, warum der Enumerator eines TStack auch vorwärts läuft, gerade hier wäre doch ein "Abräumen" logisch.
Aber dann fiel mir auch auf, dass der indizierte Zugriff überhaupt so abläuft, wie ich dachte: Ich dachte, TList sei eine klassische verkettete Liste und bei jedem Zugriff läuft er ganz von Anfang an so lange, bis er oft genug zum nächsten Element gesprungen ist. Bei großen Listen weiter hinten wäre das ja der Tod. Stattdessen ist das ja einfach nur ein Array! Das erklärt auch, was Capacity bedeutet. Wieder ein weiteres Mysterium geklärt. Die Welt ist gut. |
AW: IEnumerable rückwärts durchlaufen
Eventuell als Zusatzinfo noch:
es gibt bestimmte IEnumerable Methoden, die verzögert ausgeführt werden und andere direkt. Verzögerte Ausführung heißt, dass beim Durchlaufen erst die Elemente der Quelle durchlaufen werden (und das auch nur 1mal für einen kompletten Durchlauf) - z.B. Where oder Take Einige Operationen können das nicht - zum Beispiel Reverse. Hierbei ist die Implementierung in .Net so, dass die Quelle ausgelesen und in ein Array gepackt wird. Dieses wird dann vom letzten bis zum ersten Element zurückgegeben. Wenn man beachtet, dass hinter IEnumerable auch theoretisch eine unendliche Menge stecken kann, sieht man, dass bestimmte Operationen damit keinen Sinn machen würden. Für eine for in Schleife spielt auch der Enumerator eine Rolle, welcher einen State hat - in dem Falle einer verketteten Liste könnte er also problemlos das aktuelle Element wissen, so dass du keinen ![]() |
AW: IEnumerable rückwärts durchlaufen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz