Autor Beitrag
Daniel L.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 140
Erhaltene Danke: 14

W7, W8
TurboD Prof, Delphi Community
BeitragVerfasst: Sa 08.12.12 18:59 
Hallo,


lässt sich die Zahl der Dimensionen eines dynamischen - mehrdimensionalen Array irgendwie ermitteln?

Gruss: Daniel

Moderiert von user profile iconNarses: Titel geändert.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1448

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Sa 08.12.12 20:21 
Hallo,
zum Beispiel:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Sa 08.12.12 20:46 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
zum Beispiel:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 08.12.12 22:09 
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1448

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Sa 08.12.12 23:17 
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
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? :nixweiss:
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. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 140
Erhaltene Danke: 14

W7, W8
TurboD Prof, Delphi Community
BeitragVerfasst: So 09.12.12 02:07 
Also ich will als Variant - Parameter an ein Funktion beliebige dynamische Arrays übergeben

ausblenden 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 :wink:
Problem hat sich so erledigt.

Daniel
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: So 09.12.12 14:59 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
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? :nixweiss:


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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: 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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Mo 10.12.12 04:28 
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
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.

ausblenden volle Höhe Delphi-Quelltext
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;

  // Zum Testen ggf. einzelne Zeilen auskommentieren.
  SetLength(TestArray, 5);
  SetLength(TestArray[0], 1);
  SetLength(TestArray[1], 3);
  SetLength(TestArray[12], 4);
  SetLength(TestArray[2], 7);
  SetLength(TestArray[3], 5);
  SetLength(TestArray[4], 7);
  SetLength(TestArray[12], 4);
  SetLength(TestArray[46], 7);

  Dimension1 := 0;
  Dimension2 := 0;
  Dimension3 := 0;

  if (Length(TestArray) - High(TestArray) = 1then
    Memo1.Lines.Add('dynamisches Array');

  Dimension := 0;

  // Elemente der 1. Dimension
  Zahl := Length(TestArray);
  if Zahl > 0 then
    Dimension1 := 1;

  // Elemente der 2. Dimension
  for Schleife := 0 to High(TestArray) do
    begin
      Zahl := Zahl + Length(TestArray[Schleife]);
      // Elemente der 3. Dimension
      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;