Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Array Inhalt versetzen? (https://www.delphipraxis.net/204219-array-inhalt-versetzen.html)

Medium 9. Mai 2020 22:46

AW: Array Inhalt versetzen?
 
Es wäre alles so einfach, wenn der TE bloß eine TList<String> oder grad TStringlist einsetzen würde. Jegliche potenzielle Konvertion zur notwedigen Form ist 100%ig einfacher und performanter als all die Workarounds, die hier so auftauchen. Warum nicht einfach die geeignete Datenstruktur? Das ist doch, was einen guten Programmierer ausmacht: Das richtige Werkzeug für den jeweiligen Einsatzzweck erkennen. :?

MicMic 10. Mai 2020 08:48

AW: Array Inhalt versetzen?
 
Zitat:

Zitat von Uwe Raabe

Ich kann auch mit folgendem Code keinen Fehler feststellen (getestet in 10.3.3):
Delphi-Quellcode:
procedure RotateRight(var A: TArray<String>);
begin
  Insert(A[Length(A)], A, 0);
  Delete(A, High(A), 1);
end;

procedure RotateLeft(var A: TArray<String>);
begin
  Insert(A[0], A, Length(A));
  Delete(A, 0, 1);
end;

Bei mir geht RotateRight nicht. Ich habe diese 10.3 Community Version
Ich bin mit meinem "...Right" zufrieden. Trotzdem Danke
Delphi-Quellcode:
 Procedure TabToRight(Var A:TArray<String>);
 Var S : String;
 Begin
  S := A[Length(A)-1];
  Insert(S, Splitted, 0);
  Delete(A,Length(A)-1,1);
 End;

Zitat:

Zitat von Medium
Es wäre alles so einfach, wenn der TE bloß eine TList<String> oder grad TStringlist einsetzen würde. Jegliche potenzielle Konvertion zur notwedigen Form ist 100%ig einfacher und performanter als all die Workarounds, die hier so auftauchen. Warum nicht einfach die geeignete Datenstruktur? Das ist doch, was einen guten Programmierer ausmacht: Das richtige Werkzeug für den jeweiligen Einsatzzweck erkennen.

Ich habe es nicht ausprobiert, da ich ja eine Lösung gefunden habe und beim TList<String> erst mal schauen müsste, wo ich sonst im Programmcode was abändern muss. Ich arbeite ja an verschiedenen Stellen mit meinem Array. Wäre wohl jetzt nicht ein großes Problem mit ein paar Codeänderungen aber es geht ja jetzt. Dieses Array hat auch nicht viele Einträge. Evtl. max 20 oder so. Mein "TabToLeft" und "TabToRight" was ich hier gepostet habe, geht nun wie gewünscht.

Auch noch Danke an "himitsu" für seinen Code.

Gruß Micha

himitsu 10. Mai 2020 09:20

AW: Array Inhalt versetzen?
 
Zitat:

Zitat von MicMic (Beitrag 1464181)
Bei mir geht RotateRight nicht.

Vermutlich weil
Delphi-Quellcode:
A[Length(A)]
nicht existiert. :wink:

MicMic 10. Mai 2020 09:38

AW: Array Inhalt versetzen?
 
Zitat:

Zitat von himitsu (Beitrag 1464182)
Zitat:

Zitat von MicMic (Beitrag 1464181)
Bei mir geht RotateRight nicht.

Vermutlich weil
Delphi-Quellcode:
A[Length(A)]
nicht existiert. :wink:

Uwe meinte aber, es geht bei ihm so :)

himitsu 10. Mai 2020 09:58

AW: Array Inhalt versetzen?
 
Gute Frage: Copy&Paste-Error oder "es knallt nicht" weil Indexprüfung nicht aktiv.

MicMic 10. Mai 2020 10:07

AW: Array Inhalt versetzen?
 
Jedenfalls mit meiner "TabToRight" bin ich jetzt zufrieden. Anfangs war's ja noch alles mit "SetLength". Auch alles recht übersichtlich jetzt und für meinen Anwendungszweck supi.

Uwe Raabe 10. Mai 2020 12:09

AW: Array Inhalt versetzen?
 
Zitat:

Zitat von himitsu (Beitrag 1464186)
oder "es knallt nicht" weil Indexprüfung nicht aktiv.

Das ist tatsächlich so. Es ist aber kein Copy-Paste Error. Interessanterweise führt ein
Delphi-Quellcode:
Lenght(A) - 1
zu einem falschen Ergebnis! Ursache ist das intern aufgerufene _DynArrayInsertElem. Da wird zunächst das Array verschoben, um am Anfang Platz zu schaffen. Dadurch schiebt sich das letzte Array-Element genau unter den von
Delphi-Quellcode:
A[Length(A)]
angegebenen Speicherbereich.

himitsu 10. Mai 2020 12:43

AW: Array Inhalt versetzen?
 
Hatte nicht nachgesehn, aber würde dann das hier bestätigen.
Zitat:

Zitat von himitsu (Beitrag 1464113)
Ohh, eigentlich sollte der Wert vorher kopiert und als Parameter übergeben werden,
aber könnte wirklich sein, dass hier die Compilermagic und Codeoptimierung durchschlägt, da Insert und Delete nicht wirklich so richtige "normale" Prozeduren sind. :shock:


himitsu 10. Mai 2020 13:27

AW: Array Inhalt versetzen?
 
Man könnte es jetzt so lösen und die Prüfung deaktivieren.
Delphi-Quellcode:
procedure RotateRight(var A: TArray<String>);
begin
  {$RANGECHECKS OFF}
  Insert(A[Length(A)], A, 0);
  Delete(A, High(A), 1);
  //{$RANGECHECKS ON}  = Default ist OFF
end;

procedure RotateRight(var A: TArray<String>);
begin
  {$UNDEF _TEMP_}
  {$IFOPT R+} {$DEFINE _TEMP_} {$ENDIF} 
  {$RANGECHECKS OFF}
  Insert(A[Length(A)], A, 0);
  Delete(A, High(A), 1);
  {$IFDEF _TEMP_} {$RANGECHECKS ON} {$ENDIF} 
end;
Aber wenn irgendwann am Verhalten von INSERT was geändert wird und es dann "richtig" funktioniert,
oder wenn es schon jetzt auf verschiedenen Plattformen unterschiedliche arbeitet (Win64, Android, ...),
dann hast ein Problem.

Effektiv verbleibt aber diese Lösung:
Delphi-Quellcode:
procedure RotateRight(var A: TArray<String>);
var
  T: Temp;
begin
  T := A[High(A)];
  Insert(T, A, 0);
  Delete(A, High(A), 1);
end;

// oder :lol:
procedure RotateRight(var A: TArray<String>);
begin
  Insert(StrToInt(IntToStr(A[High(A)])), A, 0); // oder Insert(Min(A[High(A)], A[High(A)]), A, 0);
  Delete(A, High(A), 1);
end;
Test-Code:
Delphi-Quellcode:
var
  i, j: Integer;
  A: TArray<Byte>;
  B: array[0..7] of string;
begin
  {$RANGECHECKS OFF}
  SetLength(A, 10);
  for i := 0 to High(B) do
    B[i] := StringOfChar('_', 12 * 2) + ' ';

  // move first +1
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[Length(A)], A, 0); BinToHex(A[0], PChar(B[0]), Length(A));
  Delete(A, High(A), 1);      BinToHex(A[0], PChar(B[1]), Length(A));

  // move first
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[High(A)], A, 0);   BinToHex(A[0], PChar(B[2]), Length(A));
  Delete(A, High(A), 1);      BinToHex(A[0], PChar(B[3]), Length(A));

  // move first none-optimize
  {$OPTIMIZATION OFF}
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[High(A)], A, 0);   BinToHex(A[0], PChar(B[4]), Length(A));
  Delete(A, High(A), 1);      BinToHex(A[0], PChar(B[5]), Length(A));
  {$OPTIMIZATION ON}

  // move last
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[0], A, Length(A)); BinToHex(A[0], PChar(B[6]), Length(A));
  Delete(A, 0, 1);            BinToHex(A[0], PChar(B[7]), Length(A));

  for i := 0 to High(B) do for j := Length(A) downto 0 do Insert(' ', B[i], j * 2 + 3);
  ShowMessage(
    B[0] + 'first+1'#10  + B[1] + #10#10 +
    B[2] + 'first'#10    + B[3] + #10#10 +
    B[4] + 'first no'#10 + B[5] + #10#10 +
    B[6] + 'last'#10     + B[7]);
end;
Delete hat das Problem natürlich nicht, denn hier muß ja zuerst ausgelesen werden und dann wird damit die Länge geändert.
Delphi-Quellcode:
var
  i: Integer;
  A: TArray<Byte>;
  B: string;
begin
  SetLength(A, 10);
  for i := 0 to High(A) do A[i] := i;
  B := StringOfChar('_', Length(A) * 2);

  Delete(A, A[5], 1);

  BinToHex(A[0], PChar(B), Length(A));
  for i := Length(A) downto 0 do Insert(' ', B, i * 2 + 3);
  ShowMessage(B);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:37 Uhr.
Seite 3 von 3     123   

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