Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Doppelte Schleife verlassen (https://www.delphipraxis.net/183516-doppelte-schleife-verlassen.html)

Martin W 16. Jan 2015 13:33

Doppelte Schleife verlassen
 
Hi,

folgender Code aktuell:

Delphi-Quellcode:
 
var
  changed: boolean;
  varCurrActClass:         TLastActionClass;

  i:                       integer;
begin    

    changed := True;
 
     while changed do
        begin
          changed := False;
          for i := 0 to FLastActionList.Count -1 do
            begin

              varCurrActClass := FLastActionList.Items[i];

              if (...) then
                begin
                  FLastActionList.Remove(varCurrActClass);
                  FLastActionList.TrimExcess;
                  changed := True;
                  break;
                end;

              if (...) then
                begin
                  FLastActionList.Remove(varCurrActClass);
                  FLastActionList.TrimExcess;
                  changed := True;
                  break;
                end;

            end;
        end;

end;
Gibt es hierbei eine Möglichkeit, das changed "wegzuoptimieren"? Also ein Break, das sowohl die if, als auch die While Schleife abbricht?

Viele Grüße,
Martin

Neutral General 16. Jan 2015 13:39

AW: Doppelte Schleife verlassen
 
Zitat:

Also ein Break, das sowohl die if, als auch die While Schleife abbricht?
Du meinst die for- und die while-Schleife ;)

Nein sowas gibt es nicht. Es gibt nicht wirklich eine andere Möglichkeit als sich zu merken ob die äußeren schleifen abgebrochen werden sollen.

Martin W 16. Jan 2015 13:41

AW: Doppelte Schleife verlassen
 
Oh, ja klar, die for und while Schleife :roll:

Danke deiner Antwort!


Viele Grüße

Der schöne Günther 16. Jan 2015 13:44

AW: Doppelte Schleife verlassen
 
Goto :duck:

Neutral General 16. Jan 2015 13:57

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1286729)
Goto :duck:

:mrgreen: über Exceptions/Abort und einem entsprechend günstig gesetzten try-except Block ginge es auch. Aber das sind dann halt die weniger schönen Möglichkeiten.

p80286 16. Jan 2015 14:02

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1286729)
Goto :duck:

Hat mal wer Hammer und Nägel da?:evil:

Gruß
K-H

Uwe Raabe 16. Jan 2015 14:25

AW: Doppelte Schleife verlassen
 
Du kannst beide Schleifen in eine separate Methode verlagern und diese dann bei Bedarf mit Exit verlassen.

Uwe Raabe 16. Jan 2015 14:29

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von Martin W (Beitrag 1286724)
Gibt es hierbei eine Möglichkeit, das changed "wegzuoptimieren"? Also ein Break, das sowohl die if, als auch die While Schleife abbricht?

In deinem Beispiel führen die beiden Breaks aber ja gerade nicht zum Abbruch der while-Schleife, sondern zu derer Fortsetzung. Die while-Schleife würde ja nur dann beendet, wenn keine der if-Bedingungen innerhalb der for-Schleife anschlägt.

Ist das jetzt so gewollt oder war nur deine Frage falsch formuliert?

Sherlock 16. Jan 2015 15:03

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von p80286 (Beitrag 1286734)
Zitat:

Zitat von Der schöne Günther (Beitrag 1286729)
Goto :duck:

Hat mal wer Hammer und Nägel da?:evil:

Gruß
K-H

Das nicht, aber ich hätte da zwei relativ große Holzbalken, die ich beisteuern könnte.

Sherlock

himitsu 16. Jan 2015 15:05

AW: Doppelte Schleife verlassen
 
Jupp, hier geht das Exit, da sowieso die Funktion verlassen wird, nach den Schleifen.

Ihr könnt ja gern man bei Emba den Vorschlag einreichen das Break und Continue zu ändern.
(mein uralter Vorschlag im QC wurde ja nicht beachtet :cry:)

z.B.
Delphi-Quellcode:
Break 2;
Continue 2;
für das Verlassen/Fortsetzen von den inneren zwei Schleifen.

Und für For-Schleifen eventuell auch
Delphi-Quellcode:
for i1 := 0 to 10 do begin
  for i2 := 0 to 10 do begin
    ...
    Break i1;
  end;
end;
für "Breche alle Schleifen ab, bis hin zur For-Schleife mit der i1-Variable".
Eventuell kann man die Repeat- und Whileschleifen auch "benennen" und dann
Delphi-Quellcode:
Break DerName;
.


Und dann hätte ich auch gern noch ein "Self" für With-Blöcke, oder den "Alias", wie es ihn in tausenden anderen Sprachen gibt.
sogar in http://www.amazon.de/Revolutionary-G.../dp/1874416206

Popov 16. Jan 2015 15:35

AW: Doppelte Schleife verlassen
 
Ich persönlich nutze dafür immer ein Boolean:

Delphi-Quellcode:
var
  a, b: Integer;
  c: Boolean;
begin
  c := False;

  for a := 0 to 10 do
  begin
    for b := 0 to 10 do
    begin
      ShowMessage('b = ' + IntToStr(b));
      if b = 1 then
      begin
        c := True;
        Break;
      end;
    end;

    if c then Break;

    ShowMessage('a = ' + IntToStr(a));
  end;

  ShowMessage('Und weiter im Programm');
end;

Wenn es etwas unkonventionell sein darf, dann kann man das auch mit Except lösen:

Delphi-Quellcode:
var
  a, b: Integer;
begin
  try
    for a := 0 to 10 do
    begin
      for b := 0 to 10 do
      begin
        ShowMessage('b = ' + IntToStr(b));
        if b = 1 then Abort;
      end;
      ShowMessage('a = ' + IntToStr(a));
    end;
    ShowMessage('Schleifen sind durch');
  except
    ShowMessage('Hallo aus Except');
  end;
  ShowMessage('Und weiter im Programm');
end;

Der schöne Günther 16. Jan 2015 18:23

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von Linus Benedict Torvalds
If you need more than 3 levels of indentation, you're screwed anyway, and should fix your program.

Ich lasse das mal hier

Dejan Vu 16. Jan 2015 18:33

AW: Doppelte Schleife verlassen
 
Wie von Uwe Raabe schon erwähnt:
Delphi-Quellcode:
 
..
  Function ProcessAction : Boolean;
  var
    varCurrActClass : TLastActionClass;
    i : integer;

  begin    
    for i := 0 to FLastActionList.Count -1 do begin
      varCurrActClass := FLastActionList.Items[i];
      if (...) then begin
        FLastActionList.Remove(varCurrActClass);
        FLastActionList.TrimExcess;
        exit(true);
      end;
     
      if (...) then begin
        FLastActionList.Remove(varCurrActClass);
        FLastActionList.TrimExcess;
        exit(true);
      end;
    end;
    exit(false);
  end;

begin
  while ProcessAction() do;
end;
Bisserl refactoring wg. DRY wäre noch möglich. Und der Funktion solltest Du noch die passende Bezeichnung verpassen.

Goto wird nie benötigt und wer ein Flag mitschleppen muss, weil innere Schleifen verlassen, sollte refaktorisieren. Ausnahme: Höchst zeitkritische Abläufe, denn dann ist alles erlaubt. Aber ansonsten geht imho Clean Code vor Performance.

Martin W 16. Jan 2015 20:23

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von Dejan Vu (Beitrag 1286779)
Aber ansonsten geht imho Clean Code vor Performance.

Ja, daran muss ich mich auch häufiger selbst erinnnern... :mrgreen:

Danke für das Beispiel!

Sir Rufo 16. Jan 2015 20:42

AW: Doppelte Schleife verlassen
 
Wenn ich das richtig sehe, dann müsste es so auch DRY werden.
Delphi-Quellcode:
function ProcessAction : Boolean;
var
  varCurrActClass : TLastActionClass;
  i : integer;
begin
  try
    for i := 0 to FLastActionList.Count -1 do
    begin
      varCurrActClass := FLastActionList.Items[i];

      if
        {Bedingung1} (...)
        {oder} or
        {Bedingung2} (...)
      then
        begin
          FLastActionList.Remove(varCurrActClass);
          FLastActionList.TrimExcess;
          exit(true);
        end;
     
    end;
    exit(false);
  finally
    {Wenn es noch etwas zu tun gibt, wird quasi immer ausgeführt}
  end;
end;

begin
  while ProcessAction( ) do;
end;
Aber wenn ich es mir so richtig anschaue, dann müsste sich das komplett so abtüten lassen:
Delphi-Quellcode:
procedure ProcessAction;
var
  varCurrActClass : TLastActionClass;
  i : integer;
begin
    for i := FLastActionList.Count -1 downto 0 do
    begin
      varCurrActClass := FLastActionList.Items[i];

      if
        {Bedingung1} (...)
        {oder} or
        {Bedingung2} (...)
      then
        begin
          FLastActionList.Delete( i );
        end;
     
    end;
  FLastActionList.TrimExcess;
end;

Martin W 16. Jan 2015 21:38

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1286792)
Aber wenn ich es mir so richtig anschaue, dann müsste sich das komplett so abtüten lassen:
Delphi-Quellcode:
procedure ProcessAction;
var
  varCurrActClass : TLastActionClass;
  i : integer;
begin
    for i := FLastActionList.Count -1 downto 0 do
    begin
      varCurrActClass := FLastActionList.Items[i];

      if
        {Bedingung1} (...)
        {oder} or
        {Bedingung2} (...)
      then
        begin
          FLastActionList.Delete( i );
        end;
     
    end;
  FLastActionList.TrimExcess;
end;

Das mit dem downto ist eine feine Sache, so kann man wunderbar das OutOfRange verhindern ohne das in eine while Schleife zu packen :thumb: Edit: Works amazing :thumb:

Delphi-Quellcode:
      if
        {Bedingung1} (...)
        {oder} or
        {Bedingung2} (...)
      then
Eine Möglichkeit, ja aber die if Abfragen sind etwas größer, daher hatte ich das aufgeteilt um den Code Übersichtlich zu halten.

Sir Rufo 17. Jan 2015 01:38

AW: Doppelte Schleife verlassen
 
Zitat:

Zitat von Martin W (Beitrag 1286795)
Delphi-Quellcode:
      if
        {Bedingung1} (...)
        {oder} or
        {Bedingung2} (...)
      then
Eine Möglichkeit, ja aber die if Abfragen sind etwas größer, daher hatte ich das aufgeteilt um den Code Übersichtlich zu halten.

Es ist egal wie groß die sind, wenn zu groß, dann in Funktionen auslagern und dann benutzen. Sehr oft gibt es dann auch noch Überschneidungen, die man dann auch noch auslagern und wieder verwenden kann. Und schwups kann man auch die einzelnen Teilergebnisse prüfen, wenn die Abfrage mal nicht so hinhaut, wie man sich das gedacht hat.

Definitiv sollte man keinen Code doppelt schreiben, denn Änderungen müssen dann auch doppelt gepflegt werden und das ist schon wieder der Anfang vom Chaos ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:22 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