AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

For xx In xxx Schleife rückwärts?

Ein Thema von milos · begonnen am 24. Jan 2014 · letzter Beitrag vom 27. Jan 2014
Antwort Antwort
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#1

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 11:42
Dabei ist mir aufgefallen, dass die aktuelle Online-Dokumentation die Delphi-Anweisungen überhaupt nicht beinhaltet. Selbst wenn man die Anweisungen kennt und direkt danach sucht, landet man immer im entsprechenden (und unvollständigen) C++ Teil.

[edit]
http://docwiki.embarcadero.com/RADSt...nd_Anweisungen

Es gibt nur noch eine Riesenseite mit allen Anweisungen.
[/edit]
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all

Geändert von Union (24. Jan 2014 um 11:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.590 Beiträge
 
Delphi 12 Athens
 
#2

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 12:02
Wobei die FOR-IN-Schleife selber nichts mit der Reihenfolge zu tun hat.
Sie läuft einfach nur von vorhne nach hinten alle einträge durch, bis der Enumerator sagt, daß es nichts mehr gibt.

Die Reihenfolge der Daten vom Enumerator sind nicht vorgeschrieben, womit es also kein Problem ist, wenn man sich einen Enumerator erstellt, welcher die Daten in umgekehrter Reihenfolge liefert.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.052 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 14:22
Eine for..in Schleife ist per Definition dafür gedacht, dass man die Elemente in einer beliebigen Reihenfolge durchläuft. Dass sie aufgrund der aktuellen Implementierung eine bestimmte Reihenfolge haben, mag sein, ist aber nicht garantiert.

Deshalb:
Wenn die Reihenfolge wichtig ist, niemals for..in nutzen. Theoretisch kann man das zwar mit einem eigenen Enumerator sicherstellen, aber das ist nicht gerade sauber...
Besser ist es über den Index und for..downto zu gehen und den aktuellen Eintrag selbst ggf. in eine Variable zu speichern um ihn nicht immer wieder aus der Liste abrufen zu müssen.
Wobei die FOR-IN-Schleife selber nichts mit der Reihenfolge zu tun hat.
Sie läuft einfach nur von vorhne nach hinten alle einträge durch, bis der Enumerator sagt, daß es nichts mehr gibt.

Die Reihenfolge der Daten vom Enumerator sind nicht vorgeschrieben, womit es also kein Problem ist, wenn man sich einen Enumerator erstellt, welcher die Daten in umgekehrter Reihenfolge liefert.
Das ist nicht ganz korrekt. Für einen Menge Elemente, die einen Index Zugriff bieten, liefert auch ein for-in die Elemente in der gleichen Reihenfolge zurück wie mit einem for-to (nicht for-downto!). Durch die Möglichkeit, selber den Enumerator für eine for-in Schleife zu schreiben, verbietet natürlich keiner, die Elemente in einer komplett anderen Reihenfolge (oder sogar non deterministisch) zurückzuliefern (was aber imho schon an Sabotage grenzt).
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 15:08
(oder sogar non deterministisch [..] was aber imho schon an Sabotage grenzt).
Sehe ich anders. Diese Art der Schleife ist ja gerade darüber definiert, dass sie eine ungeordnete Menge an Elementen iteriert. Würde man sich in einer for..in-Schleife auf ein festgelegtes Iterationsverhalten verlassen, so wäre das extrem schlecht selbstdokumentierender Code. Ein for..to dagegen zeigt direkt eindeutig eine Laufrichtung inkl. Grenzen an. Es hat daher auch durchaus seinen wohl überlegten Sinn, dass beide Konstrukte nebeneinander existieren.
Ein for..in mit einer Abhängigkeit von einer Reihenfolge der Aufzählung würde ich daher sogar als groben Fehler ansehen, da es eine wichtige Sache stark verschleiert.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.052 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#5

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 15:45
Für arrays ist es so implementiert, dass ein for-in einem for-to entspricht.
Für alles andere (wenn ich jetzt grad außer Arrays nix vergessen habe) ist die Implementierung des enumerators, welcher über die GetEnumerator Funktion zurückgeliefert wird, dafür zuständig, welche Reihenfolge angewandt wird.

Da die Delphi Dokumentation ja nicht so ausführlich wie beispielsweise die MSDN ist, kann ich gerade nicht sagen, ob dort für TList<T>, TStrings oder sonstiges, was ein GetEnumerator (also for-in tauglich ist) implementiert, dokumentiert wurde, in welcher Reihenfolge, die Elemente zurückgeliefert werden. In allen mir bekannten Fällen, in denen intern ein Array zur Datenhaltung dient, ist hier das gleiche der Fall, wie oben bereits erwähnt (equivalent zu for-to).

Der primäre Unterschied zwischen einem for-in und einem for-to ist der Indexzugriff, den man bei einem for-in nicht hat bzw nicht benötigt, von daher sind die beiden Konstrukte in keinem Fall komplett redundant.

Ebenfalls kann ich mit einem for-in auch locker über eine endlose Menge iterieren oder über eine, deren Anzahl beim Start noch nicht feststeht.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#6

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 16:30
Für arrays ist es so implementiert, dass ein for-in einem for-to entspricht.
Reiner Zufall. Heute so, morgen anders (Rückwärtszählen geht vielleicht schneller, Speicher ist nicht mehr linear aufgebaut, wer weiß das schon).
Sich darauf zu verlassen, wie etwas implementiert ist, ist -mit Verlaub- ganz großer Käse.

Eigentlich darf man in einer For-In Schleife auch keine Änderungen an der der laufenden Enumeration zugrundeliegenden Datenstruktur vornehmen (auf Gut Deutsch: Die Liste verändern). Aber da ist Delphi wohl nicht so safe.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.052 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

AW: For xx In xxx Schleife rückwärts?

  Alt 27. Jan 2014, 13:49
Für arrays ist es so implementiert, dass ein for-in einem for-to entspricht.
Reiner Zufall. Heute so, morgen anders (Rückwärtszählen geht vielleicht schneller, Speicher ist nicht mehr linear aufgebaut, wer weiß das schon).
Sich darauf zu verlassen, wie etwas implementiert ist, ist -mit Verlaub- ganz großer Käse.

Eigentlich darf man in einer For-In Schleife auch keine Änderungen an der der laufenden Enumeration zugrundeliegenden Datenstruktur vornehmen (auf Gut Deutsch: Die Liste verändern). Aber da ist Delphi wohl nicht so safe.
Zu glauben, dass sich das Verhalten einer for-in Schleife für ein Array ändert ist eher der große Käse. Die Compiler Optimierung des rückwärts zählens auf 0 bei einer for-to Schleife wird auch nur vorgenommen, wenn der Index in der Schleife nicht benötigt wird und dementsprechend die Logik des Programms nicht verändert wird. Das trifft auf eine for-in Schleife wohl auch nur dann zu, wenn man im Schleifenrumpf nix mit der Laufvariable macht. Wobei dann die Reihenfolge auch Rille wäre.

Was die Veränderung der durchlaufenden Struktur angeht ist die Implementierung in der Delphi RTL wirklich nicht sehr dolle. In Spring4d hingegen wird dir ein Enumerator mit einer Exception ins Gesicht springen, wenn du zwischendurch die zugrundelegende Datenmenge veränderst (analog zum Verhalten in .Net).

Ich stimme den meisten hier zu, dass es gefährlich sein kann, anhand eines abstrakten Interfaces (IEnumerable<T>) auf ein Implementierungsdetail zu schließen. Deshalb würde ich in einem solchen Fall eher vorschlagen, ein weniger abstraktes zu benutzen. In Spring4d/.Net würde sich dort z.B. IList<T> anbieten. Dieses bietet direkten Indexzugriff und man kann sich sicher sein, dass implementierende Klassen den Enumerator auch in einer solchen Weise implementieren, dass die Liste von vorn nach hinten durchlaufen werden.

Im übrigen macht das .Net Framework selber bei den diversen IEnumerable<T> extension methods implizite Annahmen über die Ausführung. Schaut euch einfach mal First, Last oder ElementAt an (welche intern eine Optimierung für den Fall haben, dass es sich um IList<T> handelt).

Dass eine enumeration ein nicht erwartetes Ergebnis hat, habe ich erst kürzlich selbst erlebt, einfach mal eine PriorityQueue enumerieren und sich wundern, dass die Elemente eine andere Reihenfolge haben, als wenn man Dequeue aufruft, bis sie leer ist
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (27. Jan 2014 um 13:52 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.078 Beiträge
 
Delphi 12 Athens
 
#8

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 16:40
Da die Delphi Dokumentation ja nicht so ausführlich wie beispielsweise die MSDN ist, kann ich gerade nicht sagen, ob dort für TList<T>, TStrings oder sonstiges, was ein GetEnumerator (also for-in tauglich ist) implementiert, dokumentiert wurde, in welcher Reihenfolge, die Elemente zurückgeliefert werden.
Definiert ist dieses Verhalten für Arrays:
http://docwiki.embarcadero.com/RADSt...nd_Anweisungen
Zitat:
Array-Ausdrücke können sich auf ein- oder mehrdimensionale Arrays, Arrays mit fester Länge oder dynamische Arrays beziehen. Das Array wird in aufsteigender Reihenfolge durchlaufen, beginnend mit der unteren Array-Grenze bis zur Array-Größe minus eins.
Trotzdem passt die Syntax nicht dazu das vorauszusetzen. Das ist genauso unsauber wie bei AnsiStrings die Länge als Größe in Byte anzunehmen oder die Größe eines Pointers als Größe eines Integers anzunehmen oder...
Schlicht weil es absolut keinen Sinn macht, wenn man auf bestimmte Indizes zugreifen will (eine bestimmte Reihenfolge eben) diese nicht zu benutzen...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#9

AW: For xx In xxx Schleife rückwärts?

  Alt 24. Jan 2014, 17:06
Delphi-Quellcode:
type
  IEnumerable<T> = interface(IEnumerable)
    ///   <summary>
    ///    Inverts the order of the elements in a sequence.
    ///   </summary>
    function Reversed: IEnumerable<T>;
  end;
Quelle: Spring.Collections.pas:250

Delphi-Quellcode:
program Project1;

{$AppType Console}

{$R *.res}

uses
  System.SysUtils,
  Spring.Collections,
  Spring.Collections.Lists;

procedure Run;
type
  T = String;
var
  List: IList<T>;
  Item: T;
begin
  List := TList<T>.Create;
  List.AddRange(['Eins.', 'Zwei.', 'Drei.', 'Vier.']);
  for Item in List.Reversed do
    WriteLn(Item);
end;

begin
  try
    Run;
  except
    on E: Exception do
      WriteLn(E.ClassName + ': ' + E.Message);
  end;

  if DebugHook <> 0 then
    ReadLn;
end.
Ausgabe:
Code:
Vier.
Drei.
Zwei.
Eins.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:15 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