Delphi-PRAXiS
Seite 2 von 3     12 3      

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)

MicMic 8. Mai 2020 16:05

AW: Array Inhalt versetzen?
 
Zitat:

Zitat von himitsu (Beitrag 1464049)
Zitat:

Zitat von MicMic (Beitrag 1464042)
* Verstehe ich nicht so ganz.

Du machst da auch am Anfang ein SetLength+1, also ist am Ende natürlich auch ein SetLength-1 nötig, oder du lässt die SetLength in diesem Fall komplett weg. :zwinker:

Hmm, in der 2. Variante von "nach links verschieben" habe ich auch SetLength+1 aber kein SetLength-1. Aber das geht so.
Wenn ich für "nach rechts verschieben" die beiden SetLength's rausmache, dann verschiebt er aber nicht richtig die Inhalte.

Aber mal zur Info: Ich habe ein String "Dies,Das,Auto,Flugzeug,irgendwas" und mein Array fülle ich dann mit "a:=stringvariable.Split([','])".

himitsu 8. Mai 2020 16:55

AW: Array Inhalt versetzen?
 
Ja, aber dort entspricht das SetLength zusammen mit dem := einem Insert.

Hier hast du Insert+Delete und die SetLength (ohne eine Zuweisung).




Da man leider an dynamische Arrays (noch) keine Record-Helper hägen kann, um sich direkt solche Funktionen nachzurüsten
und da es unmöglich ist bestehende Record-Helper zu erweitern,
hab ich mir einen Record genommen, dort ein TArray<string> reingebaut, alles noch schön mit impliziten Casts und paar Methoden aufbemotzt
und mir somit eine Art TStringList gebaut, die sich von der Speicherverwaltung wie ein Array verhält, aber solche netten Methoden wie z.B. Insert, Delete und Move enthält. :stupid:

DieDolly 8. Mai 2020 17:21

AW: Array Inhalt versetzen?
 
Zitat:

Ist halt nicht so einfach auf variable Arraylängen anpassbar.
Verstehe das Problem nicht. Das ist ein einfacher Switch über ein string array.

Medium 8. Mai 2020 18:09

AW: Array Inhalt versetzen?
 
Zitat:

Zitat von DieDolly (Beitrag 1464064)
Zitat:

Ist halt nicht so einfach auf variable Arraylängen anpassbar.
Verstehe das Problem nicht. Das ist ein einfacher Switch über ein string array.

Nein. Der Fragesteller möchte nicht 2 Elemente tauschen, sondern das erste zum letzten machen, und alle nach dem ersten sollen um einen Indext nach unten rutschen. (Und auch den umgekehrten Weg.) Hatte mich bei deiner ersten Antwort schon gewundert, was das mit dem Problem des TE zu tun hat - außer man rauscht ein Mal kräftig auf "komplizierte" Weise durch das ganze Array.

MicMic 9. Mai 2020 08:03

AW: Array Inhalt versetzen?
 
Die eine Richtung mit:
Code:
 SetLength(A,Length(A)+1);
 Insert(A[Length(A)-1], A, 0);
 Delete(A,Length(A)-1,1);
 SetLength(A,Length(A)-1);
die nur mit "SetLength+1" und "SetLength-1" geht, habe ich geändert.

Nur ein:
Code:
 Insert(A[Length(A)-1], A, 0);
 Delete(A,Length(A)-1,1);
reicht aber hier nicht. Er setzt hier den vorletzten Eintrag an den Anfang. Auf den letzten Eintrag im Array habe ich gar keinen Zugriff. Das lieg wohl am Aufbau von "Insert" (wegen "Length(A)-1").

Ich habe mir jedenfalls entsprechende Prozeduren gemacht (für beide Richtungen):
Code:
 Procedure TabToLeft(Var A:TArray<String>);
 Begin
   Insert(A[0], A, Length(A));
   Delete(A,0,1);
 End;

 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;
So geht's dann komplett ohne "SetLength".

Danke für die Hilfe meiner Problemlösung.

Gruß Micha

himitsu 9. Mai 2020 14:40

AW: Array Inhalt versetzen?
 
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:

Über die Record-Operatoren hast hier dann mehr Glück, weil die komplett extrem unoptimierbar sind.


Nja, direkt ist es so eigentlich auch nicht optimal, denn hier wird ja zwei mal die Länge des Arrays geändert und im extremfall auch alles bis zu zwei Mal komplett umkopiert.

Andreas13 9. Mai 2020 15:17

AW: Array Inhalt versetzen?
 
Anstatt der Änderung der Array-Länge und des damit verbundenen (internen) Umkopierens der Inhalte könntest Du relativ einfach eine Art von Ringpuffer realisieren. Hierbei würde lediglich ein Zeiger auf das Array-Element zeigen und Du könntest diesen Zeiger (Pointer) Inkrementieren bzw. Dekrementieren und den Inhalt nur im Bedarfsfall anzeigen. Allerdings weiß ich nicht, ob eine solche Lösung zu Deiner Anwendung passt oder nicht.
Gruß, Andreas

Andreas13 9. Mai 2020 15:22

AW: Array Inhalt versetzen?
 
Noch einfacher wäre ein gleichlanges Integer-Array, in welchem die Elemente auf die gewünschte Position des String-Arrays zeigen. Damit kannst Du die Reihenfolge durch Änderung der "Integer-Zeiger" einfach ändern und auch die String-Inhalte
Delphi-Quellcode:
StringArray[IntegerArray[i]]
anzeigen.

Uwe Raabe 9. Mai 2020 15:58

AW: Array Inhalt versetzen?
 
Zitat:

Zitat von Andreas13 (Beitrag 1464119)
Noch einfacher wäre ein gleichlanges Integer-Array, in welchem die Elemente auf die gewünschte Position des String-Arrays zeigen.

Da die Strings selbst auch nur als Pointer in den Array-Elementen vorliegen, ergibt sich m.E. hier kein nennenswerter Vorteil.

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;

himitsu 9. Mai 2020 17:06

AW: Array Inhalt versetzen?
 
Delphi-Quellcode:
var
  A: TArray<Integer>;
  T: Integer;
  i: Integer;
begin
  // Hoch - BubbleMode
  for i := High(A) - 1 downto 0 do begin
    T := A[i];
    A[i] := A[i + 1];
    A[i + 1] := T;
  end;

  // Hoch - SingleMove
  T := A[0];
  for i := High(A) - 1 downto 0 do
    A[i] := A[i + 1];
  A[High(A)] := T;

  // Runter
  T := A[High(A)];
  for i := High(A) downto 1 do
    A[i] := A[i - 1];
  A[0] := T;

  // Hoch - FullMove
  T := A[0];
  FinalizeArray(@A[0], TypeInfo(T), 1); // eigentlich FinalizeRecord, aber siehe InitializeRecord
  Move(A[1], A[0], High(A) * SizeOf(A));
  InitializeArray(@A[High(A)], TypeInfo(T), 1); // InitializeRecord, aber das ist nicht öffentlich und geht letztendlich eh nur auf die Array-Funktion
  A[High(A)] := T;

  // ohne das Finalize und Initialize, wenn man für T "immer" eine Variable von ungemanagtem Typ verwendet, wie z.B. Integer oder ein Byte-Array,
  // denn bei Typen ala String, DynArray, Interface oder Variant zerschießt man sich sonst das automatische Speichermanagement, wenn man das nicht beachtet (eines von Beidem)
  Move(A[0], T, SizeOf(A));
  Move(A[1], A[0], High(A) * SizeOf(A));
  Move(T, A[High(A)], SizeOf(A));
Die Dinge ohne Move haben den Vorteil, dass man nichts falsch und kaputt machen kann. (so lange man die Indexprüfung nicht deaktiviert)


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:48 Uhr.
Seite 2 von 3     12 3      

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