Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Mehrdimensionales Array mit SetLength() vergrößern


Delphi2009lover - So 29.11.09 20:53
Titel: Mehrdimensionales Array mit SetLength() vergrößern
Hi,

ich habe ein Mehrdimensionales Array und möchte während der Laufzeit die Größe des Arrays verändern.

Mit SetLength(dasArray,2); hab ich ja die größe des Arrays auf 2 gestellt, aber wie geht das bei mehrdimensionalen Arrays

(var dynArray: array of integer;)


Moderiert von user profile iconNarses: Topic aus VCL (Visual Component Library) verschoben am So 29.11.2009 um 23:06


Marc. - So 29.11.09 21:05

In dem Du entsprechend die Länge der Subelemente änderst:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  MyArray: Array of Array of Integer;
...
  SetLength(MyArray, 2);
  // o-->
  // o--> 
  SetLength(MyArray[0],3);
  // o--> X X X
  // o-->

Grüße


Delphi2009lover - So 29.11.09 21:22

Ok das hab ich verstanden, wenn ich jetzt


Delphi-Quelltext
1:
 ListInfos: Array of Array [1..6of WideString;                    


schreibe, und dann


Delphi-Quelltext
1:
SetLength(ListInfos, 10);                    


kann ich dann z.B.


Delphi-Quelltext
1:
ListInfos[9][6] := 'Letztes Element';                    


schreiben?


Marc. - So 29.11.09 21:31

Richtig!
Dynamisch, aber schlecht lesbar, könnte man das letzte Element auch so ansprechen:

Delphi-Quelltext
1:
2:
3:
4:
  MyArray: Array of Array [1..6of WideString;
...
  SetLength(MyArray, 10);
  MyArray[High(MyArray)][High(MyArray[High(MyArray)])] := 'Letztes Element'// MyArray[9][6]


Delphi2009lover - So 29.11.09 21:35

Danke das hat sehr geholfen, die Funktion High() kannte ich aber schon :wink:


catweasel - So 29.11.09 21:56

Hi,

Es aber geht auch: Setlength(MyArray,5,6);

Das ergibt ein 5*6 Array.

Die Setlength() funktion kann mehr als eine Dimensionsparameter verarbeiten.

Das mit dem komplizierten Ansprechen :


Delphi-Quelltext
1:
MyArray[High(MyArray)][High(MyArray[High(MyArray)])] := 'Letztes Element'// MyArray[9][6]                    


relativiert sich sobald mann durch das array durchiteriert.. Dann ists doch ganz übersichtlich, da beim setzen ja die Grösse bekannt ist:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
MyArray : array of array of integer;
a,b,x,y : integer;

a := 3;
b := 8;

setlength(MyArray,a,b);

for x := 0 to a-1 do
  for y := 0 to b-1 do
    MyArray[x][y] := 0;


Mann kann auch hier wieder mit high() arbeiten.

Mal ein grundsätzlich anderer Vorschlag:

Wenn man mal ein Elemnt aus der Mitte entfernen möchte sind Arrays eher unflexibel.
Leite eine Klasse von TList ab. In der kannst du dann beliebige records ablegen.
Im Prinzip ist die TStringList ja auch nix anderes als ein String Array mit Speichermöglichkeit.
(Und den bequemen Möglichkeiten Elemente hinzuzufügen, zu entfernen, so ganz ohne setlength().)

Hierml ein kleiner Rohbau. (Statt integer werte speichere ich hier records). Vielleicht ist das ja was für dich:


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:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
unit UResourceHeader;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Dialogs;

type
  TResourceType = (dText,dImage,dVideo,dAudio);

type
  TResourceRecord = record
   Name : string[64];
   DataType : TResourceType;
   Offset : longint;
   Size : longint;
  end;

type
  TDataPointer = ^TResourceRecord;

type
  TResourceHeader = class(TList)
  private
    container : TDataPointer;
    diskfile : file;
    ResoureFileName : string;
  public
    constructor create;reintroduce;
    destructor destroy;reintroduce;
    function additem(data:TResourceRecord): boolean;
    procedure moditem(index:integer;data: TResourceRecord);
    procedure deleteitem(index:integer);
    function getitem(index:integer):TResourceRecord;
    function getheader(header:string):TResourceRecord;
    function isinlist(tilename:string):integer;
    procedure loadfromfile(filename:string);
    procedure savetofile(filename:string);
  end;


implementation


{ TResourceHeader }

function TResourceHeader.additem(data: TResourceRecord):boolean;
var
x : integer;
begin
Result := true;
x := isinlist(data.Name);
if (x>=0then
  begin
  Result := false;
  showmessage('A record with that name already exists!');
  exit;
  end;
new(container);
container.Name := data.Name;
container.DataType := data.DataType;
container.Offset := data.Offset;
container.Size := data.Size;
Add(container);
end;

constructor TResourceHeader.create;
begin
  inherited create;
end;

procedure TResourceHeader.deleteitem(index: integer);
begin
  inherited Delete(index);
end;

destructor TResourceHeader.destroy;
begin
  inherited destroy;
end;

function TResourceHeader.getitem(index: integer): TResourceRecord;
begin;
container := items[index];
Result := container^;
end;


function TResourceHeader.getheader(header: string): TResourceRecord;
var
x : integer;
begin
for x := 0 to count-1 do
  begin
  container := items[x];
  if container.Name = header then break;
  end;
Result := container^;
end;

function TResourceHeader.isinlist(tilename: string): integer;
var
x : integer;
container : TResourceRecord;
begin
Result := -1;
for x := 0 to count-1 do
  begin
  container := getitem(x);
  if container.Name = tilename then
    begin
    Result := x;
    exit;
    end;
  end;
end;

procedure TResourceHeader.loadfromfile(filename: string);
var
container : TResourceRecord;
begin
Self.Clear;
assignfile(diskfile,filename);
reset(diskfile,sizeof(TResourceRecord));
repeat
  blockread(diskfile,container,1);
  additem(container);
until eof(diskfile) = true;
close(diskfile);
end;

procedure TResourceHeader.moditem(index: integer; data: TResourceRecord);
var
container : TDataPointer;
begin
new(container);
container^ := data;
Items[index] := container;
end;

procedure TResourceHeader.savetofile(filename: string);
var
x : integer;
container : TResourceRecord;
begin
assignfile(diskfile,filename);
rewrite(diskfile,sizeof(TResourceRecord));
for x := 0 to Count-1 do
  begin
  container := getitem(x);
  blockwrite(diskfile,container,1);
  end;
close(diskfile);
end;

end.


Regards,
Cateasel


Marc. - So 29.11.09 22:15

user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:
Es aber geht auch: Setlength(MyArray,5,6);

Jap. Ich weiß aber auch nicht, warum mir das vorhin nicht eingefallen ist. :autsch:
Ansonsten kann ich Dir nur beipflichten.