Autor |
Beitrag |
Daniel L.
      
Beiträge: 140
Erhaltene Danke: 14
W7, W8
TurboD Prof, Delphi Community
|
Verfasst: Sa 08.12.12 18:59
Hallo,
lässt sich die Zahl der Dimensionen eines dynamischen - mehrdimensionalen Array irgendwie ermitteln?
Gruss: Daniel
Moderiert von Narses: Titel geändert.
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Sa 08.12.12 20:21
Hallo,
zum Beispiel:
Delphi-Quelltext 1: 2: 3: 4:
| setlength(x,a,b); ... dimension1:=length(x); dimension2:=length(x[0]); |
In dimension1 steht der Wert a, in dimension2 das b und für mehr Dimensionen entsprechend weiter.
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 08.12.12 20:32
Wobei die Unterarrays ja auch verschieden groß sein können. Und dann muss man natürlich auch einzeln prüfen, ob das Array, dessen Element geprüft werden soll, auch groß genug ist. (Length auf ein nicht existentes Arrayelement gibt eine Zugriffsverletzung.)
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Sa 08.12.12 20:46
Mathematiker hat folgendes geschrieben : | Hallo,
zum Beispiel:
Delphi-Quelltext 1: 2: 3: 4:
| setlength(x,a,b); ... dimension1:=length(x); dimension2:=length(x[0]); |
In dimension1 steht der Wert a, in dimension2 das b und für mehr Dimensionen entsprechend weiter.
Beste Grüße
Mathematiker |
Müßte das nicht in eine Kopf- oder Fußschleife inkl. eines Fehlerbehandlungscodes (s. jaenickes Beitrag) gepackt werden? Es geht ja schließlich darum, die Anzahl der Dimensionen zu ermitteln?!
Ergänzung: Problematisch wird das auch vor der Dimensionierung. Deklariert ist das Array ja schon mit soundsoviel Dimensionen. Es scheint mir, als müßten vor diesen dimensionsbezogenen Abfragen die einzelnen Dimensionen erst einmal (mit Setlength) dimensioniert werden (welch ein herrlicher verbaler, aber nicht inhaltlicher Pleonasmus).
Ergänzung 2: Ist mit einer Schleife wohl nicht hinzubekommen. Wie will man length(a), length(a[0]), length(a[0,0]) usw., also den Inhalt in den eckigen Klammern, systematisch aufbauen und vergrößern, bis sich eine Exzeption ergibt?
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 08.12.12 22:09
Delphi-Laie hat folgendes geschrieben : | Ergänzung: Problematisch wird das auch vor der Dimensionierung. Deklariert ist das Array ja schon mit soundsoviel Dimensionen. Es scheint mir, als müßten vor diesen dimensionsbezogenen Abfragen die einzelnen Dimensionen erst einmal (mit Setlength) dimensioniert werden (welch ein herrlicher verbaler, aber nicht inhaltlicher Pleonasmus). |
Nein, du kannst die Unterarrays auch alle gleich groß machen, indem du SetLength entsprechend viele Parameter übergibst.
Du kannst sie aber auch einzeln und auch verschieden setzen.
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Sa 08.12.12 23:17
Delphi-Laie hat folgendes geschrieben : | Es geht ja schließlich darum, die Anzahl der Dimensionen zu ermitteln?! |
Richtig, so lautet die Frage. Habe ich nicht richtig gelesen und folglich falsch beantwortet.
Allerdings ergibt sich für mich dann die Frage, wozu man das eigentlich braucht?
Gibt es denn überhaupt die Möglichkeit, dass sich ein dynamisches Array selbst Dimensionen hinzufügen kann, ohne dass ich es "merke"?
Oder geht es hier darum, die Daten aus einer fremden Quelle, deren Struktur unbekannt ist, auszulesen?
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Daniel L. 
      
Beiträge: 140
Erhaltene Danke: 14
W7, W8
TurboD Prof, Delphi Community
|
Verfasst: So 09.12.12 02:07
Also ich will als Variant - Parameter an ein Funktion beliebige dynamische Arrays übergeben
Delphi-Quelltext 1:
| function sort (V : variant) : variant; |
Die Funktion muss zuersteinmal die Anzahl der Dimensionen ermitteln.
Jetzt ist mir eingefallen: ich kann ja die Anzahl der Dimensionen als zusätzlichen Parameter
mitübergeben
Problem hat sich so erledigt.
Daniel
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: So 09.12.12 14:59
Mathematiker hat folgendes geschrieben : | Delphi-Laie hat folgendes geschrieben : | Es geht ja schließlich darum, die Anzahl der Dimensionen zu ermitteln?! |
Richtig, so lautet die Frage. Habe ich nicht richtig gelesen und folglich falsch beantwortet.
Allerdings ergibt sich für mich dann die Frage, wozu man das eigentlich braucht?  |
Nun, man kann sie m.e. jedenfalls nicht mit den Sprachumfang des Delphis ermitteln: Wollte man mit seltlength(a), setlength(a[0], setlength(a[0,0] oder auch nur mit der Adressierung a[0], a[0,0], in einer try-Answeisung, das ermitteln so scheitert das schon bei der Syntaxprüfung, wenn die Anzahl der deklarierten Dimensionen überschritten wird. Hinzu kommt, das schrieb ich schon oben, daß man die mit der Anzahl der Dimensionen mitwachsenden Indizes [0], [0,0], [0,0,0] usw. nicht in Form einer Schleife wachsen lassen kann, man müßte es explizieren, und dann wären verdammt viele Dimensionen zu beachten.
Kurzum, was durch den Quelltext deklariert und damit fix(iert) ist, bedarf keiner Ermittlung zur Laufzeit.
Auch bei der Übergabe eines Arrays als Parameter sind n.m.w. zwar die Anzahl der Elemente pro Dimension, nicht jedoch die Anzahl der Dimensionen variabel.
Edit: Las soeben erst Daniels Beitrag. Also, mit variant würde ich ohnehin nie "rummachen", jedenfalls nicht ohne Notwendigkeit, und vor einer solchen stand ich noch nie.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: So 09.12.12 19:06
Da bei Variants fast alles möglich ist, dürfte die Übergabe der Anzahl nicht ausreichen.
QuickAndDirty-Beispiel wie man an die Infos kommt.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| Function Sort(va:Variant):Variant; begin if VarIsArray(va) then Showmessage(IntToStr( VarArrayHighBound(va[3],1)));
end;
procedure TForm6.Button1Click(Sender: TObject); var a:Variant; b:Variant; begin
b := VarArrayOf([1,2,3,'test']); a := VarArrayOf(['Nase',17,'bär',b]); Sort(a); end; |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mo 10.12.12 04:28
Delphi-Laie hat folgendes geschrieben : | Auch bei der Übergabe eines Arrays als Parameter sind n.m.w. zwar die Anzahl der Elemente pro Dimension, nicht jedoch die Anzahl der Dimensionen variabel. |
Die definierten Dimensionen nicht, aber die benutzten. Zum Ausprobieren kannst Du ja mal die beiden letzten SetLength-Anweisungen im Beispiel mit einem dreidimensionalen Array auskommentieren. Man kann das Beispiel sicherlich noch optimieren.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64:
| procedure TMainform.Button1Click(Sender: TObject); var TestArray : Array of Array of Array of Integer; Schleife : Integer; Schleife1 : Integer; Zahl : Integer; Dimension : Integer; Dimension1: Integer; Dimension2: Integer; Dimension3: Integer; begin Memo1.Clear;
SetLength(TestArray, 5); SetLength(TestArray[0], 1); SetLength(TestArray[1], 3); SetLength(TestArray[1, 2], 4); SetLength(TestArray[2], 7); SetLength(TestArray[3], 5); SetLength(TestArray[4], 7); SetLength(TestArray[1, 2], 4); SetLength(TestArray[4, 6], 7);
Dimension1 := 0; Dimension2 := 0; Dimension3 := 0;
if (Length(TestArray) - High(TestArray) = 1) then Memo1.Lines.Add('dynamisches Array');
Dimension := 0;
Zahl := Length(TestArray); if Zahl > 0 then Dimension1 := 1;
for Schleife := 0 to High(TestArray) do begin Zahl := Zahl + Length(TestArray[Schleife]); if Length(TestArray[Schleife]) > 0 then begin Dimension2 := 1; for Schleife1 := 0 to High(TestArray[Schleife]) do begin Zahl := Zahl + Length(TestArray[Schleife, Schleife1]); if Length(TestArray[Schleife, Schleife1]) > 0 then Dimension3 := 1; end; end; end; Memo1.Lines.Add('Anzahl Elemente: ' + IntToStr(Zahl)); Dimension := Dimension1 + Dimension2 + Dimension3; Memo1.Lines.Add('Anzahl benutzte Dimensionen: ' + IntToStr(Dimension)); TestArray := nil; end;
procedure TMainform.FormCreate(Sender: TObject); begin ReportMemoryLeaksOnShutdown := true; end; |
|
|
|