AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

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
Seite 3 von 4     123 4      
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#21

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

  Alt 25. Jan 2014, 17:07
Eben. In der Benutzung ist es aber exakt gleich. Heißt: Man müsste bei der Betrachtung stets nachschauen von was denn die Klasse, die in einem Quelltext benutzt wird, abgeleitet ist, um beurteilen zu können, ob ein Quelltext macht was er soll.

Und das ist ein No-Go in sauberem Quelltext.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

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

  Alt 25. Jan 2014, 17:34
Aber wie am Beispiel des TList.Reversed, kann man die Funktion auch direkt am Quellcode dokumentieren.

Also wenn man eine bestimmre Reihenfolge benötigt, dann kann man auch einen passenden Enumerator auch direkt angeben.
Wie z.B. einen rückwärttslaufenden Enumerator, oder Einen, welcher die Liste vorher cached, wenn man innerhalb der Schleife die Liste verändern möchte,
oder einen Enumerator, welcher die Liste gefilltert durchläuft und nur bestimmte Einträge behandelt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Panthrax

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

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

  Alt 25. Jan 2014, 18:09
In der Benutzung ist es aber exakt gleich. Heißt: Man müsste bei der Betrachtung stets nachschauen von was denn die Klasse, die in einem Quelltext benutzt wird, abgeleitet ist, um beurteilen zu können, ob ein Quelltext macht was er soll.
Richtig! Vielleicht noch einmal zur Erinnerung (und unter Berücksichtigung der Bindung durch den Compiler), der Aufruf einer Methode wird konzeptionell zurückgeführt auf den Aufruf einer Routine mit dem Objekt als erstem Parameter:
Delphi-Quellcode:
Objekt.Methode(Argument);
Methode(Objekt, Argument);
Kein Parameter ohne Bedeutung: Das Objekt stellt einen Zusammenhang mit Daten her und die Klasse des Objekts stellt einen Zusammenhang mit Funktionen her. Stichwort: Polymorphie.

Anderes Beispiel:
Delphi-Quellcode:
program Project1;

{$AppType Console}

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

type
  T = String;

procedure Enumerate(const Caption: String; const Enumerable: IEnumerable<T>);
var
  Value: T;
begin
  WriteLn(Caption);
  for Value in Enumerable do
    WriteLn(Value);
end;

procedure Run;
var
  Collection1: IList<T>;
  Collection2: ISet<T>;
  Value: T;
begin
  Collection1 := TList<T>.Create;
  Collection2 := THashSet<T>.Create;

  Collection1.Add('Eins.');
  Collection1.Add('Eins.');
  Collection1.Add('Zwei.');
  Collection1.Add('Drei.');
  Collection1.Add('Vier.');
  Collection1.Add('Drei.');

  for Value in Collection1 do
    Collection2.Add(Value);

  Enumerate('Aufzählung 1', Collection1);
  Enumerate('Aufzählung 2', Collection2);
end;

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

  if DebugHook <> 0 then
    ReadLn;
end.
Ausgabe:
Code:
Aufzählung 1
Eins.
Eins.
Zwei.
Drei.
Vier.
Drei.
Aufzählung 2
Zwei.
Drei.
Eins.
Vier.
Das verdeutlicht vielleicht noch einmal auf andere Weise, dass das Objekt und seine Klasse bedeutsam sind für das, welche Funktion mit welchen Daten ausgeführt werden soll. Dieses Verhalten ist erwünscht und der wesentliche Grund dafür, warum wir Polymorphie nutzen. Bspw. Add ist für eine Liste eben anders definiert als für eine Menge. Gleichermaßen ist eine Aufzählung für eine Liste klar definiert, und kann durchaus von anderen Aufzählungen anderer Typen abweichen. Gleichsam sind beides Sammlungen und beide aufzählbar, was bei der Routine Enumerate nützlich ist. Und eine Menge bietet eben keinen indizierten Zugriff auf ihre Elemente, der für eine For-to-Schleife benötigt wird. Er müsste erst künstlich geschaffen werden. Genauso bei dem TDictionary<...> -Beispiel von oben; IDictionary<NativeInt, String> und IList<TPair<NativeInt, String>> sind eben unterschiedliche Typen, auch wenn beide einen IEnumerator<TPair<NativeInt, String>> anbieten.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#24

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

  Alt 25. Jan 2014, 19:40
Du bist ja ein richtiger Fachmann.
Was ist in diesem Beispiel die Liste?
Die Tabelle.
Ein Enumerator hat genauso viel mit einer Liste zu tun wie ein Cursor mit einer Tabelle.
Der Cursor zählt die Query auf, der Enumerator die Liste. Wo und wie ist denn die Reihenfolge definiert, wenn die nicht explizit festgelegt ist? Heute kommen die Daten so, morgen so. Glaubste nicht? Tja, dann fehlt dir was.
Zitat:
Eine andere Reihenfolge ist ein Fehler.
Ach, echt? Hatte ich erwähnt, das es sich um eine TSortedList handelt (1,2,3). oder eine TLinguisticSortedList? (3,1,2). Oder eine Hashmap? Oder. Oder. Oder.
Also nochmal, für Hausfrauen, zum Mitschreiben: Die Reihenfolge der Aufzählung ist implementierungsabhängig, mithin undefiniert (obwohl meistens deterministisch) und im Einzelfall durchaus heute anders als morgen. Sie darf auch nichtdeterministisch sein (RDBMS), d.h. jedesmal in einer anderen Reihenfolge. Der einzige Grund, weshalb das i.a. nicht der Fall ist, ist doch der, das es naheliegend ist, das ein Array oder eine Liste die Elemente mit einem Index aufzählt. Aber wie sieht es mit der Reihenfilge bei einer Hashmap aus? Oder einem Baum? Wie ist denn die Reihenfolge hier? Infix, Prefix, Postfix? Was ist mit einem ungerichteten Graphen? Trie? etc. etc. etc.

Deshalb hat man doch gerade das gemeinsame IEnumerable-Paradigma, um die einzelnen Elemente wenigstens aufzählen zu können, auch Mengen ohne innere Ordnung. Mann, so schwer kann das doch nicht sein.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#25

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

  Alt 25. Jan 2014, 19:40
Code, bei dem ich erst die Klassenhierarchie studieren müsste um herauszufinden wie meine Schleife läuft (und dies relevant ist), würde ich dem Autor sowas von um die Ohren knallen, das glaubst du gar nicht. Das ist bewusstes torpedieren von Teamarbeit und Produktivität.
"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
Panthrax

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

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

  Alt 25. Jan 2014, 20:42
Zitat:
Eine andere Reihenfolge ist ein Fehler.
Ach, echt? Hatte ich erwähnt, das es sich um eine TSortedList handelt (1,2,3). Oder eine TLinguisticSortedList? (3,1,2). Oder eine Hashmap? Oder. Oder. Oder.
Nein, hatten Sie nicht. Was nicht dasteht kann nicht bewertet werden. Im übrigen widersprechen Sie auf ihren Umwegen ja auch nicht. Meine vorigen Beiträge sind auch ausreichend Antwort bis hierhin. Vielleicht finden Sie ja wirklich bestätigend viele Leute in Ihrem Umfeld, die Sie bitten können einmal aufzuzählen was auf Ihrer Einkaufsliste steht, und die dann wirklich jedes Mal die Liste anders rauf- und runterspringen. Ich würde ja meinen sie würden es einfach von vorn nach hinten durchlesen. In der Tat, so schwer kann das doch nicht sein.

Nun denn, wenn es darum geht Liste zu nennen, was keine ist, und Dinge nicht so zu implementieren, wie es ihr Name sagt, und man dabei Unsicherheit wider der Vernunft streut, während man beim Programmieren selbst immer wieder in die Defensive gerät - denn es könnte sich ja immer alles auch ein bisschen anders verhalten - dann sind wir beim Etikettenschwindel angekommen:
Code, bei dem ich erst die Klassenhierarchie studieren müsste um herauszufinden wie meine Schleife läuft (und dies relevant ist), würde ich dem Autor sowas von um die Ohren knallen, das glaubst du gar nicht. Das ist bewusstes torpedieren von Teamarbeit und Produktivität.
Stichwort: Produktivität. - Ich bin raus.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#27

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

  Alt 27. Jan 2014, 00:41
Im Grunde streitet ihr euch, ob ein foreach auf einem Iterator arbeitet (=> Reihenfolge hängt vom Iterator ab, kann je nach Art des Iterators bekannt oder unbekannt sein) oder auf einer Datenstruktur (=> Reihenfolge ist bei unbekannter Datenstruktur unbekannt, im Zweifelsfall Index benutzen). Mir ist die Iterator-Sichtweise lieber.

Was die Index-Fanatiker (SCNR) nicht berücksichtigen: Gerade der Zugriff durch den Index ist unter Umständen nicht wirklich effizient.
Man denke nur mal an eine verkettete Liste: Der Index ist eigentlich überhaupt nicht interessant, man möchte nur einmal die Liste von vorne nach hinten durchlaufen. Trotzdem darf man jetzt Länge der Liste mal zu dem jeweils gesuchten Index laufen. Hurra, schon ist aus einer linearen eine quadratische Laufzeit geworden

Wenn ich einen bestimmten Iterator benutze/fordere, dann kann ich mich auf die Reihenfolge verlassen, die dieser garantiert.
Die Anforderungen an den Iterator sollte man natürlich irgendwo dokumentieren
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#28

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

  Alt 27. Jan 2014, 11:10
Nettes Beispiel! Ich gebe zu, dass es hier tatsächlich ein Grenzfall ist. Und auch wenn ich bei verketteten Listen durchaus nicht die Nase rümpfen würde, wenn dort jemand "altbacken" mit einer while-Schleife und CurrentItem := CurrentItem.Next; durchrauscht, sehe ich eine potenzielle Vereinfachung durch for..in hier. In solch einem Fall würde ich mir dann aber schon einen explizit benutzten Iterator mit sinnvollem Namen wünschen, oder zumindest ein Wort dazu im Kommentar. for Item in List.ForwardIterator do o.ä. Das würde sich wieder selbst dokumentieren wie der Index, ohne den von dir genannten Nachteil.
"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.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#29

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

  Alt 27. Jan 2014, 14: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 14:52 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

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

  Alt 27. Jan 2014, 14:59
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
Das dürfte im Delphi vermutlich auch auf TStack und TQueue zutreffen (solange man sie nicht als FIFO benutzt).
Also falls die überhaupt einen Enumerator haben.

Und wenn, müsste der Enumerator, bei sowas, nicht sogar der Liste geleert werden? (jedes Element müsse trausgenommen werden, sobaldes verarbeitet wird )
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (27. Jan 2014 um 15:02 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 20:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz