Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Array mit Recordinhalten löschen (https://www.delphipraxis.net/171894-array-mit-recordinhalten-loeschen.html)

Mojito 30. Nov 2012 16:56

Array mit Recordinhalten löschen
 
Hallo liebe Delphi-Freunde,

wie lösche ich am Sinnvollsten einen Array bzw. leere ihn? Bei einem einfachen Records würde ich es einfach mit ='' tun, aber mein Array hat zahlreiche "Unterelemente": array(1..10).Haus, array(1..10).Land, array(1..10).Nation, array(1..10).Name.

Wie lösche ich das gesamte Element an einem bestimmten Index?

Vielen Dank!

Furtbichler 30. Nov 2012 17:04

AW: Array mit Recordinhalten löschen
 
Äh... ohne Quellcode? Keine Ahnung.

Mojito 2. Dez 2012 15:08

AW: Array mit Recordinhalten löschen
 
Hier der Code.

Delphi-Quellcode:
Type
TErfassung = record
    Mitarbeiter: string[25];
    Vorgesetzter: string[25];
    PNummer: string[6];
    Gehaltsstufe: 1..10;

TDataArray = array[1..15] of TErfassung;

var
  Data: TDataArray;
Ich möchte nun Beispielsweise alle Daten in Data[1] löschen und das ohne die einzelnen Unterbereiche wie Data.mitarbeiter anzusteuern. Gibt es ein schlanke Möglichkeit, alle Daten auf einmal an einem Bestimmten Indexwert(wie Data[1]) zu löschen?
Vielen Dank!

Bummi 2. Dez 2012 15:21

AW: Array mit Recordinhalten löschen
 
So lange Du nur ShortStrings wie in Deinem Beispiel verwendest:
Delphi-Quellcode:
  ZeroMemory(@data[1].Mitarbeiter,SizeOf(data[1]));

sx2008 2. Dez 2012 15:45

AW: Array mit Recordinhalten löschen
 
Irgendwie seltsam, dass Delphi Programmierer so blind sind und immer nur Arrays sehen wo in anderen Programmiersprachen (z.B. Python, C#,...Lisp!) schon längst Listen verwendet werden.

Arrays und Listen sind sich sehr ähnlich, aber nur aus Listen kann man schmerzfrei Elemente löschen.
Intern können Listen auch über Arrays nachgebildet werden aber entscheidend ist was dem Programmierer als API angeboten wird:

(dynamische) Arrays
* Wahlfreier Zugriff auf Elemente (über Index)
* nachträgliches Vergrössern/Verkleinern des Array

Listen
* Wahlfreier Zugriff auf Elemente (über Index und Inhalt)
* automatisches Vergrössern/Verkleinern der Liste
* Löschen von Elementen (ohne das Löcher zurückbleiben)
* Einfügen von Elementen an beliebiger Stelle

Popov 2. Dez 2012 16:13

AW: Array mit Recordinhalten löschen
 
Vor allem spätestens sein TObjectList (k. A. ab welchem Delphi). Wobei TList auch nicht viel komplizierter ist, aber TObjectList macht es endgültig Kinderleicht.

DeddyH 2. Dez 2012 16:16

AW: Array mit Recordinhalten löschen
 
Dann muss man aus dem Record aber erst einmal eine Klasse machen.

Popov 2. Dez 2012 16:30

AW: Array mit Recordinhalten löschen
 
Also bei dem oberen Beispiel wäre es kein Akt. record gegen class tauschen, auf property verzichten, der Rest mit TObjectList.

Oder etwas aufwändiger - eine Klasse ableiten.

DeddyH 2. Dez 2012 17:45

AW: Array mit Recordinhalten löschen
 
Oder je nach Delphi-Version eine generische Liste (ich wundere mich, dass das noch niemand vorgeschlagen hat).

Furtbichler 2. Dez 2012 18:11

AW: Array mit Recordinhalten löschen
 
Zitat:

Zitat von sx2008 (Beitrag 1194008)
Irgendwie seltsam, dass Delphi Programmierer so blind sind und immer nur Arrays sehen wo in anderen Programmiersprachen (z.B. Python, C#,...Lisp!) schon längst Listen verwendet werden.

Arrays sind schneller und wenn ich die Schmerzfrei-Lösch-Funktionalität nicht brauche, hänge ich mir keine Liste ans Bein. Warum auch?

Im Übrigen kann man auch mit FaustkeilenArrays trefflich und performant Elemente löschen. Vor allen Dingen kann man damit eins: Lernen, wie es geht.

sx2008 2. Dez 2012 21:22

AW: Array mit Recordinhalten löschen
 
Zitat:

Zitat von Furtbichler (Beitrag 1194022)
Arrays sind schneller und wenn ich die Schmerzfrei-Lösch-Funktionalität nicht brauche, hänge ich mir keine Liste ans Bein. Warum auch?

Wie ich schon gesagt habe, viele Delphi Entwickler sind einfach blind gegenüber Techniken die sich in anderen Programmiersprachen schon längst durchgesetzt haben.
Delphi-Quellcode:
 // a.)
// löschen eines Elements in einem Array
var
  i, x : integer;
begin
  x := 4; // Element Position die gelöscht werden soll
  for i:= x+1 to High(MyArray) do
  begin
    MyArray[i-1] := MyArray[i];
  end;
  SetLength(MyArray, Length(MyArray)-1);
end;

// b.)
// und jetzt das Gleiche mit einer Liste
MyList.Delete(4);
Und jetzt stelle man sich vor, dass man 5 versch. Arrays bzw. Listen hat.
Welcher Lösung wäre zu bevorzugen 5 * a.) oder 5 * b.) ?
Den Code bei a.) habe einfach so hingeschrieben; es ist gut möglich
dass er Fehler hat.
(Es sind übrigens min. 2 Fehler enthalten - wer findet sie?)
Bei b.) ist es ausgeschlossen, dass ein Fehler enthalten ist.

Furtbichler 2. Dez 2012 21:28

AW: Array mit Recordinhalten löschen
 
Ich verwende auch in C# Arrays, wenn mir das reicht, insofern bin ich kein blinder Delphi-Entwickler.

Übrigens lösche ich in Arrays, in dem ich z.B. das letzte Element in den zu löschenden Index kopiere, die Anzahl verringere und freue mich, das ich das in O(1) hinbekommen habe.

Aber Du musst schon genau lesen, was ich schreibe. Wenn ich nicht löschen muss, sondern z.B. nur einen Container für ein paar Dinger brauche, nehme ich ein Array. Sonst etwas anderes. Eine Liste nehme ich selten, eher eine Map, Dictionary oder whatever.

Bjoerk 2. Dez 2012 21:56

AW: Array mit Recordinhalten löschen
 
Schwierig sind am Anfang Ins und Del. Hat man das aber einmal "geschafft", wo ist das Problem?

Delphi-Quellcode:
procedure TIntegerList.Ins(Index, Value: integer);
var
  I: integer;
begin
  SetCount(FCount + 1);
  for I:= FCount - 1 downto Index + 1 do
    FItems[I]:= FItems[I - 1];
  SetItem(Index, Value);
end;

procedure TIntegerList.Del(Index: integer);
var
  I: integer;
begin
  for I:= Index to FCount - 2 do
    FItems[I]:= FItems[I + 1];
  SetCount(FCount - 1);
end;
Dennoch, grundsätzlich gebe ich Dir Recht. Seit ich TList ect. für mich entdeckt habe, leite ich mir zu 80 % was ab, bet TList auch z.B. wegen dem genialen QuickSort (Sort(@MyCompare) und gut ist.

Nur für mathematische Gleichungssysteme ect., da sind m.E. Array's sozusagen unschlagbar.

Furtbichler 2. Dez 2012 22:41

AW: Array mit Recordinhalten löschen
 
Natürlich es es kein Problem, es ist nur blöd, das immer selbst zu coden. Also verwendet man, wenn möglich, andere Datenstrukturen. Das war zwar nicht Thema dieses Threads, aber wenn wir schon beim Thema sind....

Bjoerk 2. Dez 2012 22:52

AW: Array mit Recordinhalten löschen
 
Ja. Dreimal Ja. Das war eigentlich ein Antwort auf #11. :)

BUG 2. Dez 2012 23:27

AW: Array mit Recordinhalten löschen
 
Zitat:

Zitat von Furtbichler (Beitrag 1194046)
Übrigens lösche ich in Arrays, in dem ich z.B. das letzte Element in den zu löschenden Index kopiere, die Anzahl verringere und freue mich, das ich das in O(1) hinbekommen habe.

Wenn man so mit Arrays arbeitet, hat mal schon fast eine Speicherverwaltung mit fester Blocklänge.
Wenn man eine direkte Freiblockliste anstellen eines "Pegelstands" verwendet, kann man sogar auf das potenziell aufwendige Kopieren des letzten Elements verzichten :)

himitsu 3. Dez 2012 01:31

AW: Array mit Recordinhalten löschen
 
Gerade für die Datensicherheit beim Bearbeiten von Arrays hab ich endlich mal einen Vorschlag gemacht. (darf man gerne für voten)
http://qc.embarcadero.com/wc/qcmain.aspx?d=110391
Die schnelleren Zugriffe über Move und Co. sind da ja schonmal ganz schön fehleranfällig.

Derartige Codes kann man aber auch schon in älteren Delphis nutzen, außer daß man sich dort die Funktionen für jeden Arraytypen einzeln implementieren müste/sollte.

Sir Rufo 3. Dez 2012 08:26

AW: Array mit Recordinhalten löschen
 
Zitat:

Zitat von himitsu (Beitrag 1194052)
Gerade für die Datensicherheit beim Bearbeiten von Arrays hab ich endlich mal einen Vorschlag gemacht. (darf man gerne für voten)
http://qc.embarcadero.com/wc/qcmain.aspx?d=110391

Kannst du mir erklären, wie das hier funktioniert, denn das verstehe ich nicht (in der class procedure Swap)
Delphi-Quellcode:
  if @Value = @Value then
    exit;
Müsste das nich eher
Delphi-Quellcode:
  if @Value1 = @Value2 then
    exit;
heißen?

himitsu 3. Dez 2012 09:28

AW: Array mit Recordinhalten löschen
 
Dieser böse Copy&Paste-Notepadprogrammierung-Codevervollständigung funktioniert auch nich immer. :(


Hmm, warum kann ich via WebQC nix editieren, was über QCApp geschrieben wurde?

Bjoerk 3. Dez 2012 11:33

AW: Array mit Recordinhalten löschen
 
Himitsu, in der Insert ist das überflüssig und in der Remove sogar falsch?

Delphi-Quellcode:
FillChar(Values[Index], SizeOf(T), 0);

himitsu 3. Dez 2012 12:28

AW: Array mit Recordinhalten löschen
 
Ins Insert muß es rein, denn wenn das z.B. ein Array of String oder IInterface ist, dann muß dort der Speicher freigegeben/genullt werden, ohne die Referenzzählung zu nutzen.
Aber beim Remove hast du Recht, da geht es auf den falschen Index. (muß
Delphi-Quellcode:
Values[High(Values)]
nullen)

Statt FillChar könnte man zwar auch InitializeRecord verwenden, aber FillChar dürfte locker ausreichen.

Bei Remove und Insert wurden Felder kopiert, womit eines der Felder nun doppelt existiert, aber die doppelte "Referenz" nicht in eventuell vorhandenen Referenzzählungen beachtet wurde, darum muß diese eventuelle Referenz "vernichtet" werden, bzw. es wirde für gewisse Typen die Speicherverwaltung nicht angepaßt.
(dyn. Array, String, Interface, Variant und Records mit den Zuvorgenannten)



Nja, Emba wird doch hoffentlich seine neu eingefühten Unittests darauf anwenden, bzw. bei Übernahme der Codes nochmal einen Blick drauf werfen. :angle2:


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