Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Suche Alternative zu Array (https://www.delphipraxis.net/112150-suche-alternative-zu-array.html)

Yheeky 15. Apr 2008 22:51


Suche Alternative zu Array
 
Hi,

ich wollte mal fragen, ob es in Delphi eine Alternative zum Datentyp Array gibt.
Ein Array muss man ja initialisieren, genauso wie in Sprachen wie z.B. C++, C#, etc...
C# aber zum Beispiel bietet andere Typen an, mit denen man ebenfalls eine Art Array erstellen kann (z.b. list<>). Gibt es sowas in Delphi auch?

Wäre interessant zu wissen. Danke!

Dunkel 15. Apr 2008 23:01

Re: Suche Alternative zu Array
 
TList und davon abgeleitete Klassen z.B. ?!

Kroko1999 16. Apr 2008 04:20

Re: Suche Alternative zu Array
 
Wäre interessant zu wissen, was Du machen willst, ansonsten ...

mkinzler 16. Apr 2008 05:41

Re: Suche Alternative zu Array
 
Einen dynamischen Array kann mann auch zur Laufzeit in der Größe verändern. Besser ist aber die Löung mit einer Liste (TList siehe Beitrag Dunkel).

semo 16. Apr 2008 07:14

Re: Suche Alternative zu Array
 
Schließe mich da Kroko1999 an: Frage ist, was du machen willst.
Weitere Alternative: TObjectList
TStings / TStringlist

Yheeky 16. Apr 2008 08:54

Re: Suche Alternative zu Array
 
Es ist eigentlich ne allgemeine Frage, aber ein Beispiel: Wenn ich drei verschiedene Daten speichern möchte wie z.B. Automarke, Modell und Anzahl Türen. Normalerweise wäre das in einem Array:

Delphi-Quellcode:
arr[0][0] = 'Opel';
arr[0][1] = 'Astra';
arr[0][2] = '3';
arr[1][0] = 'VW';
arr[1][1] = 'Golf';
arr[1][2] = '5';
Aber bei einem Array muss ich ja immer die Größe mit angeben und das ist bei C# beim Typ list<> z.B. nicht so.

mkinzler 16. Apr 2008 08:56

Re: Suche Alternative zu Array
 
Dann nimm halt eine Liste (TList, TStringList, TObjectList, ...)

DeddyH 16. Apr 2008 08:57

Re: Suche Alternative zu Array
 
Und wenn Du Dir eine Klasse TAuto definierst mit den genannten Eigenschaften, kannst Du deren Objekte prima in einer TObjectList verwalten, ohne die Größe zu kennen.

Sherlock 16. Apr 2008 08:57

Re: Suche Alternative zu Array
 
Wie wäre es mit eine Klasse TAuto, deren Objekte Du dann in einer ObjectList ablegst?


Edit: duh, zu langsam...

Sherlock

semo 16. Apr 2008 09:02

Re: Suche Alternative zu Array
 
dann erstellst du dir ein record:

Delphi-Quellcode:
type
  TAuto = record
    Marke: string;
    Modell: string;
    Tueren: Integer;
  end;
  PAuto = ^TAuto;
Und mit einer TList oder einem Array kannst Du dann Deine Records bzw. Pointer auf Reocrds verwalten.


Delphi-Quellcode:
var
  AList: TList;
  Auto1: PAuto;
  Auto2: PAuto;
begin
  ...
  AList := TList.Create();
  try
    Alist.Add(Auto);
    ...
    Auto2 := AList[0];
  finally
    AList.Free();
  end;

Nuclear-Ping 16. Apr 2008 10:59

Re: Suche Alternative zu Array
 
Zitat:

Zitat von Yheeky
Wenn ich drei verschiedene Daten speichern möchte wie z.B. Automarke, Modell und Anzahl Türen. Normalerweise wäre das in einem Array: [...]

Also wenn man sowas in C "normalerweise" in (so-)einem Array ablegt, dann muss ich sagen, dass ich sehr froh bin, mit Delphi zu arbeiten. :mrgreen:
In den Kinderschuhen von Pascal und Delphi lernt man doch bereits, Records zu verwenden und mit Arrays umzugehen (für die Lernwilligen). Wo lernt man bitte sowas in C? :shock:

Hador 16. Apr 2008 15:06

Re: Suche Alternative zu Array
 
Zitat:

Zitat von Nuclear-Ping
Also wenn man sowas in C "normalerweise" in (so-)einem Array ablegt, dann muss ich sagen, dass ich sehr froh bin, mit Delphi zu arbeiten. :mrgreen:
In den Kinderschuhen von Pascal und Delphi lernt man doch bereits, Records zu verwenden und mit Arrays umzugehen (für die Lernwilligen). Wo lernt man bitte sowas in C? :shock:

Vorsicht! C# != C

Zitat:

Zitat von Yheeky
Aber bei einem Array muss ich ja immer die Größe mit angeben und das ist bei C# beim Typ list<> z.B. nicht so.

Du kannst wenn du willst auch ein Array dynamisch in der Länge verändern:

Delphi-Quellcode:
...
var
  a: array of String;
begin
  SetLenth(a, 5); // Nun hast du schonmal 5 Speicherstellen
  a[0] := 'blubb';
  ...
  SetLength(a, 25); //Un nun hast du 25 Speicherstellen
end;
Schöner ist es aber wie schon gesagt mit einer Liste. Ich bevorzuge dabei die TObjectList von Delphi bzw. bei nonVCL-Projekten neme ich meine eigene TObjList.

Yheeky 16. Apr 2008 15:20

Re: Suche Alternative zu Array
 
Zitat:

Zitat von M. Hassmann
dann erstellst du dir ein record:

Delphi-Quellcode:
type
  TAuto = record
    Marke: string;
    Modell: string;
    Tueren: Integer;
  end;
  PAuto = ^TAuto;
Und mit einer TList oder einem Array kannst Du dann Deine Records bzw. Pointer auf Reocrds verwalten.


Delphi-Quellcode:
var
  AList: TList;
  Auto1: PAuto;
  Auto2: PAuto;
begin
  ...
  AList := TList.Create();
  try
    Alist.Add(Auto);
    ...
    Auto2 := AList[0];
  finally
    AList.Free();
  end;

Okay, aber wie kann ich die Daten füllen? Wenn ich auf Auto.Marke zugreife kommt bei mir ne Fehlermeldung (Speicherzugriffverletzung).

semo 16. Apr 2008 15:26

Re: Suche Alternative zu Array
 
Delphi-Quellcode:
type
  TAuto = record
    Marke: string;
    Modell: string;
    Tueren: Integer;
  end;
  PAuto = ^TAuto;

procedure TForm4.FormCreate(Sender: TObject);
var
  AList: TList;
  Auto1: PAuto;
  Auto2: PAuto;
begin
  AList := TList.Create();
  try
    Auto1 := New(PAuto);
    Auto1.Marke := 'blubb';
    Alist.Add(Auto1);
    Auto2 := AList[0];
    ShowMessage(Auto2^.Marke);
  finally
    AList.Free();
  end;
end;
mal eben zusammengehackt.
Speicher sollte nach new() auch wieder freigegeben werden mit dispose

Yheeky 16. Apr 2008 15:37

Re: Suche Alternative zu Array
 
Ah, cool...funktioniert auch! :-)

Warum das ^ in der Zeile:
Delphi-Quellcode:
ShowMessage(Auto2^.Marke);
Funktioniert doch auch ohne?!

Danke!!!

DeddyH 16. Apr 2008 15:40

Re: Suche Alternative zu Array
 
Dass es auch ohne funktioniert, liegt an der Compiler-Magic, richtig ist es auf jeden Fall mit ^.

Yheeky 17. Apr 2008 20:07

Re: Suche Alternative zu Array
 
Hab doch noch mal ne Frage, weil bei mir was nicht funktioniert.
Ich habe folgenden Code, mit dem ich XML Daten auslese. Diese sollen dann in eine TList:

Delphi-Quellcode:
type
  TDaten = record
    ID : Cardinal;
    Key : String;
    Value : String;
  end;

  PDaten = ^TDaten;

//...

var I, J : integer;
    neuerDatensatz : PDaten;
begin
  XML := newXMLDocument;
  XML.XML.Text := XMLString;
  XML.Active := True;

  // Datensatzlist (result) erstellen
  result := TList.Create;

  // Werte zählen
  for I := 0 to XML.DocumentElement.ChildNodes.Count - 1 do
    begin
      for J := 0 to XML.DocumentElement.ChildNodes[XMLNode].ChildNodes.Count - 1 do
      begin
        // neuen Datensatz erstellen
        neuerDatensatz := new(PDaten);

        neuerDatensatz.ID := i;
        neuerDatensatz.Key := XML.DocumentElement.ChildNodes[I].ChildNodes[J].NodeName;
        neuerDatensatz.Value := XML.DocumentElement.ChildNodes[I].ChildNodes[J].NodeValue;

        result.Add(neuerDatensatz);
      end;

    end;

end;
Das result ist aber leider immer leer, egal was ich mache :-(
Kann mir jemand sagen, wieso ich keine Daten erhalte? Wenn ich statt result eine lokale Variable erstelle und sie am Ende result zuweise, funktioniert es übrigens auch nicht.

Wäre cool, wenn mir jemand helfen könnte.

semo 17. Apr 2008 20:27

Re: Suche Alternative zu Array
 
das ist doch ein neues thema bzw eine neue frage die du hier stellst. fange also bitte einen neuen thread dazu an, danke.

Yheeky 17. Apr 2008 20:37

Re: Suche Alternative zu Array
 
Naja, es handelt sich ja immer noch um die Alternative von einem Array, klar könnte man da ein neuen Thread aufmachen, aber ich glaube, dass das Problem relativ schnell abgehandelt sein wird, weil vermutlich nur ein kleiner Fehler drin ist...deswegen versuche ich´s nochmal in dem Thread.

semo 17. Apr 2008 20:40

Re: Suche Alternative zu Array
 
Zitat:

Delphi-Quellcode:
var I, J : integer;
    neuerDatensatz : PDaten;
begin
  XML := newXMLDocument;
  XML.XML.Text := XMLString;
  XML.Active := True;

  // Datensatzlist (result) erstellen
  result := TList.Create;

  // Werte zählen
  for I := 0 to XML.DocumentElement.ChildNodes.Count - 1 do
    begin
      for J := 0 to XML.DocumentElement.ChildNodes[XMLNode].ChildNodes.Count - 1 do
      begin
        // neuen Datensatz erstellen
        neuerDatensatz := new(PDaten);

        neuerDatensatz.ID := i;
        neuerDatensatz.Key := XML.DocumentElement.ChildNodes[I].ChildNodes[J].NodeName;
        neuerDatensatz.Value := XML.DocumentElement.ChildNodes[I].ChildNodes[J].NodeValue;

        result.Add(neuerDatensatz);
      end;

    end;

end;

kannst du auch bitte den funktionkopf posten?
und vorab: es ist unschön eine tlist in einer funktion zu erzeugen und diese als ergebnis der funktion zurückzugeben.

marabu 17. Apr 2008 20:46

Re: Suche Alternative zu Array
 
Hallo Christian,

aufregender Code. Schau dir aber mal deinen Index an:

Delphi-Quellcode:
for J := 0 to XML.DocumentElement.ChildNodes[I {XMLNode}].ChildNodes.Count - 1 do
Gute Nacht

Yheeky 17. Apr 2008 20:53

Re: Suche Alternative zu Array
 
Zitat:

Zitat von marabu
Hallo Christian,

aufregender Code. Schau dir aber mal deinen Index an:

Delphi-Quellcode:
for J := 0 to XML.DocumentElement.ChildNodes[I {XMLNode}].ChildNodes.Count - 1 do
Gute Nacht

Ohje!! :shock:

Das soll natürlich so heissen:

Delphi-Quellcode:
function TForm1.LeseDaten(XMLString : String) : TList;
var I, J : integer;
    neuerDatensatz : PDaten;
    tempList : TList;
begin
  XML := newXMLDocument;
  XML.XML.Text := XMLString;
  XML.Active := True;

  // Datensatzlist erstellen
  tempList := TList.Create;

  // Werte zählen
  for I := 0 to XML.DocumentElement.ChildNodes.Count - 1 do
    begin
      for J := 0 to XML.DocumentElement.ChildNodes[I].ChildNodes.Count - 1 do
      begin
        // neuen Datensatz erstellen
        neuerDatensatz := new(PDaten);

        neuerDatensatz.ID := i;
        neuerDatensatz.Key := XML.DocumentElement.ChildNodes[I].ChildNodes[J].NodeName;
        neuerDatensatz.Value := XML.DocumentElement.ChildNodes[I].ChildNodes[J].NodeValue;

        tempList.Add(neuerDatensatz);

        // Lösche Datensatz
        Dispose(neuerDatensatz);
      end;

    end;

    result := tempList;

end;
PS: War das gute Nacht auf den Code bezogen? ;-)

Wenn nicht, dir auch ne gute Nacht! :-D

marabu 18. Apr 2008 07:46

Re: Suche Alternative zu Array
 
Liste der Anhänge anzeigen (Anzahl: 1)
Moin Christian,

Zitat:

Zitat von Yheeky
... War das gute Nacht auf den Code bezogen? ...

natürlich nicht - ich wollte mich lediglich Richtung Bett abmelden.

Du machst da einige nicht so schöne Sachen, aber richtig mies wird es, wenn du einen Zeiger auf einen dynamisch angeforderten Speicherplatz in deine Liste aufnimmst, den Speicher aber sofort wieder freigibst. Das geht auch besser:

Delphi-Quellcode:
const
  RECORDNAME = 'computerdaten';

procedure ExtractValues(doc: IDOMDocument; recNo: Cardinal; s: TStrings);
var
  dlRecs: IDOMNodeList;
  dnRec: IDOMNode;
  dnFld: IDOMNodeEx;
begin
  with doc.documentElement as IDOMNodeSelect do
  begin
    dlRecs := selectNodes(RECORDNAME);
    dnRec := dlRecs.item[Pred(recNo)];
    s.Clear;
    dnFld := dnRec.firstChild as IDOMNodeEx;
    while Assigned(dnFld) do
    begin
      s.Values[dnFld.nodeName] := dnFld.Text;
      dnFld := dnFld.nextSibling as IDOMNodeEx;
    end;
  end;
end;
Freundliche Grüße

Yheeky 23. Apr 2008 22:13

Re: Suche Alternative zu Array
 
Zitat:

Zitat von marabu
Du machst da einige nicht so schöne Sachen, aber richtig mies wird es, wenn du einen Zeiger auf einen dynamisch angeforderten Speicherplatz in deine Liste aufnimmst, den Speicher aber sofort wieder freigibst.

Mache ich das denn mit dem dynamischen Speicher?

Delphi-Quellcode:
type
  TDaten = class(TObject)
    ID : Cardinal;
    Key, Value : String;
  end;

  TDatenliste = class(TObjectList)
  protected
    function getItem(Index: Cardinal): TDaten; virtual;
    procedure setItem(Index: Cardinal; Objekt: TDaten); virtual;
  public
    function Add(Objekt: TDaten): Cardinal; virtual;
    function Remove(Objekt: TDaten): Cardinal; virtual;
    function IndexOf(Objekt: TDaten): Cardinal; virtual;
    procedure Insert(Index: Cardinal; Objekt: TDaten); virtual;
    property Items[index: Cardinal]: TDaten read getItem write setItem; default;
  end;

//...

function TDatenliste.getItem(Index: Cardinal): TDaten;
  begin
    Result := TDaten(inherited Items[Index]);
  end;

  procedure TDatenliste.setItem(Index: Cardinal; Objekt: TDaten);
  begin
    inherited Items[Index] := Objekt;
  end;

  function TDatenliste.Add(Objekt: TDaten): Cardinal;
  begin
    Result := inherited Add(Objekt);
  end;

  function TDatenliste.IndexOf(Objekt: TDaten): Cardinal;
  begin
    Result := inherited IndexOf(Objekt);
  end;

  procedure TDatenliste.Insert(Index: Cardinal; Objekt: TDaten);
  begin
    inherited Insert(Index, Objekt);
  end;

  function TDatenliste.Remove(Objekt: TDaten): Cardinal;
  begin
    Result := inherited Remove(Objekt);
  end;

//...

function TForm1.LeseDaten(Dateitext : String) : TDatenliste;
var newEntry : TDaten;
    tempDatenliste : TDatenliste;
    i, j : Cardinal;
begin
  XML := newXMLDocument;
  XML.XML.Text := Dateitext;
  XML.Active := True;

  tempDatenliste := TDatenliste.Create;

  for i := 0 to XML.DocumentElement.ChildNodes.Count - 1 do
    begin
    for j := 0 to XML.DocumentElement.ChildNodes[i].ChildNodes.Count - 1 do
      begin
        newEntry := TDaten.Create;

        newEntry.ID := i;
        newEntry.Key := XML.DocumentElement.ChildNodes[i].ChildNodes[j].NodeName;
        newEntry.Value := XML.DocumentElement.ChildNodes[i].ChildNodes[j].NodeValue;

        tempDatenliste.Add(newEntry);
      end;
    end;

  result := tempDatenliste;

end;
Was mit aufgefallen ist: wenn ich den Debugger laufen lasse und nach jedem Durchlauf der for-Schleife in tempDatenliste schaue, steht da irgendwie nichts drin. Es wird mit () angezeigt...was mich wundert ist, dass am Ende trotzdem die richtige Liste ausgegeben wird. Vielleicht hängt das ja noch mit einigen Schwachpunkten zusammen.

Wie kann ich denn den Code hier noch verbessern?


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