wildzero
asked on
Remove item from dynamic array
Hmm ok must be having a slow day!
How can I remove an item from a dynamic array?
If I have an array of 50 items, and I want to remove 3-4 from around the midddle / end of the array - how can I go about doing that?
Can I set some to null / nil and then setlength again?
How can I remove an item from a dynamic array?
If I have an array of 50 items, and I want to remove 3-4 from around the midddle / end of the array - how can I go about doing that?
Can I set some to null / nil and then setlength again?
Try this
Unit1.dfm
========
object Form1: TForm1
Left = 157
Top = 159
Width = 472
Height = 354
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Memo1: TMemo
Left = 32
Top = 16
Width = 193
Height = 249
Lines.Strings = (
'Memo1')
TabOrder = 0
end
object Button1: TButton
Left = 248
Top = 96
Width = 145
Height = 33
Caption = 'Del 3,4,5'
TabOrder = 1
OnClick = Button1Click
end
end
Unit1.pas
=======
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
MyArrayType = Double;
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
x:array of MyArrayType;
procedure DisplayArray;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function DeleteArray(var Source:array of MyArrayType;LenSource:Inte ger;
Del_IndexList:array of Integer; DelCount:Integer):Integer;
Function IsInDel_IndexList(idx:Inte ger):Boole an;
var i:Integer;
begin
Result:=False;
for i:=0 to DelCount do
begin
if Del_IndexList[i]=idx then
begin
Result:=True;
Break;
end;
end;
end;
var CurIdx,DCount:Integer;
begin
CurIdx:=0;
DCount:=0;
While CurIdx<LenSource do
begin
if IsInDel_IndexList(CurIdx) then Inc(DCount);
if CurIdx-DCount>-1 then
Source[CurIdx-DCount]:=Sou rce[CurIdx ];
inc(CurIdx);
end;
Result:=DelCount;
end;
procedure TForm1.DisplayArray;
var i:Integer;
begin
Memo1.Clear;
for i:=0 to length(x)-1 do Memo1.Lines.Add(FloatToStr (x[i]));
end;
procedure TForm1.FormCreate(Sender: TObject);
var i:Integer;
begin
SetLength(x,10);
for i:=0 to 9 do x[i]:=i+1;
DisplayArray;
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
SetLength(X,length(X)-Dele teArray(X, length(X), [3,4,5],3) );
DisplayArray;
end;
end.
Unit1.dfm
========
object Form1: TForm1
Left = 157
Top = 159
Width = 472
Height = 354
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Memo1: TMemo
Left = 32
Top = 16
Width = 193
Height = 249
Lines.Strings = (
'Memo1')
TabOrder = 0
end
object Button1: TButton
Left = 248
Top = 96
Width = 145
Height = 33
Caption = 'Del 3,4,5'
TabOrder = 1
OnClick = Button1Click
end
end
Unit1.pas
=======
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
MyArrayType = Double;
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
x:array of MyArrayType;
procedure DisplayArray;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function DeleteArray(var Source:array of MyArrayType;LenSource:Inte
Del_IndexList:array of Integer; DelCount:Integer):Integer;
Function IsInDel_IndexList(idx:Inte
var i:Integer;
begin
Result:=False;
for i:=0 to DelCount do
begin
if Del_IndexList[i]=idx then
begin
Result:=True;
Break;
end;
end;
end;
var CurIdx,DCount:Integer;
begin
CurIdx:=0;
DCount:=0;
While CurIdx<LenSource do
begin
if IsInDel_IndexList(CurIdx) then Inc(DCount);
if CurIdx-DCount>-1 then
Source[CurIdx-DCount]:=Sou
inc(CurIdx);
end;
Result:=DelCount;
end;
procedure TForm1.DisplayArray;
var i:Integer;
begin
Memo1.Clear;
for i:=0 to length(x)-1 do Memo1.Lines.Add(FloatToStr
end;
procedure TForm1.FormCreate(Sender: TObject);
var i:Integer;
begin
SetLength(x,10);
for i:=0 to 9 do x[i]:=i+1;
DisplayArray;
end;
procedure TForm1.Button1Click(Sender
begin
SetLength(X,length(X)-Dele
DisplayArray;
end;
end.
best solution would be using one call to copy memory.
This is the 'problem' of dynamic arrays... actions like these are soooo sloooowww...
I'll post an example using copymemory later.
This is the 'problem' of dynamic arrays... actions like these are soooo sloooowww...
I'll post an example using copymemory later.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hmmm true, I was going to but then I would have to write the code for adding / finding the index of an deleting records from the list wouldn't I?
I am using the suggestion that xr1140 has posted (actually, I was using the code from about.com which happens to look like his :P)
Interested in this TList approach.
Upping points
I am using the suggestion that xr1140 has posted (actually, I was using the code from about.com which happens to look like his :P)
Interested in this TList approach.
Upping points
this one seems to work
var
myList : TList;
procedure delArrayItem(Index: Integer);
var obj : TmyObjType;
begin
if Index < 0 then Exit;
if Index > myList.Count then Exit;
obj := myList.Items[Index];
myList.Delete(Index);
FreeAndNil(obj);
end;
var
myList : TList;
procedure delArrayItem(Index: Integer);
var obj : TmyObjType;
begin
if Index < 0 then Exit;
if Index > myList.Count then Exit;
obj := myList.Items[Index];
myList.Delete(Index);
FreeAndNil(obj);
end;
ASKER
Is a record classed as an object?
How would I got about adding/editing a record on a list?
(points upped)
How would I got about adding/editing a record on a list?
(points upped)
same thing from the above link
uMain.dfm
===================
object Form1: TForm1
Left = 449
Top = 295
Width = 484
Height = 231
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object butAdd: TButton
Left = 5
Top = 10
Width = 176
Height = 21
Caption = 'Add item to list'
TabOrder = 0
OnClick = butAddClick
end
object Memo1: TMemo
Left = 185
Top = 5
Width = 281
Height = 191
TabOrder = 1
end
object butDisplay: TButton
Left = 5
Top = 170
Width = 176
Height = 26
Caption = 'Display list content'
TabOrder = 2
OnClick = butDisplayClick
end
object butRemove: TButton
Left = 5
Top = 55
Width = 101
Height = 21
Caption = 'Remove index'
TabOrder = 3
OnClick = butRemoveClick
end
object Edit1: TEdit
Left = 110
Top = 55
Width = 71
Height = 21
TabOrder = 4
Text = '0'
end
end
uMain.pas
===================
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TmyObjType = class
Name : String;
constructor Create(S: string);
end;
TForm1 = class(TForm)
butAdd: TButton;
Memo1: TMemo;
butDisplay: TButton;
butRemove: TButton;
Edit1: TEdit;
procedure butAddClick(Sender: TObject);
procedure butDisplayClick(Sender: TObject);
procedure butRemoveClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
myList : TList;
implementation
{$R *.dfm}
constructor TmyObjType.Create(S: string);
begin
Name := S;
end;
procedure delArrayItem(Index: Integer);
var
obj : TmyObjType;
begin
if Index > myList.Count then Exit;
if Index < 0 then Exit;
obj := myList.Items[Index];
myList.Delete(Index);
FreeAndNil(obj);
end;
procedure TForm1.butAddClick(Sender: TObject);
var
obj : TmyObjType;
begin
if myList = nil then begin
myList := TList.Create;
end;
obj := TmyObjType.Create( 'Item with index - ' + IntToStr(myList.Count) );
myList.Add(obj);
end;
procedure TForm1.butDisplayClick(Sen der: TObject);
var i: integer;
begin
memo1.Clear;
for i := 0 to (myList.Count-1) do begin
memo1.Lines.Add( TmyObjType(myList.Items[i] ).Name );
end;
end;
procedure TForm1.butRemoveClick(Send er: TObject);
begin
delArrayItem( StrToInt(Edit1.Text) );
end;
end.
uMain.dfm
===================
object Form1: TForm1
Left = 449
Top = 295
Width = 484
Height = 231
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object butAdd: TButton
Left = 5
Top = 10
Width = 176
Height = 21
Caption = 'Add item to list'
TabOrder = 0
OnClick = butAddClick
end
object Memo1: TMemo
Left = 185
Top = 5
Width = 281
Height = 191
TabOrder = 1
end
object butDisplay: TButton
Left = 5
Top = 170
Width = 176
Height = 26
Caption = 'Display list content'
TabOrder = 2
OnClick = butDisplayClick
end
object butRemove: TButton
Left = 5
Top = 55
Width = 101
Height = 21
Caption = 'Remove index'
TabOrder = 3
OnClick = butRemoveClick
end
object Edit1: TEdit
Left = 110
Top = 55
Width = 71
Height = 21
TabOrder = 4
Text = '0'
end
end
uMain.pas
===================
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TmyObjType = class
Name : String;
constructor Create(S: string);
end;
TForm1 = class(TForm)
butAdd: TButton;
Memo1: TMemo;
butDisplay: TButton;
butRemove: TButton;
Edit1: TEdit;
procedure butAddClick(Sender: TObject);
procedure butDisplayClick(Sender: TObject);
procedure butRemoveClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
myList : TList;
implementation
{$R *.dfm}
constructor TmyObjType.Create(S: string);
begin
Name := S;
end;
procedure delArrayItem(Index: Integer);
var
obj : TmyObjType;
begin
if Index > myList.Count then Exit;
if Index < 0 then Exit;
obj := myList.Items[Index];
myList.Delete(Index);
FreeAndNil(obj);
end;
procedure TForm1.butAddClick(Sender:
var
obj : TmyObjType;
begin
if myList = nil then begin
myList := TList.Create;
end;
obj := TmyObjType.Create( 'Item with index - ' + IntToStr(myList.Count) );
myList.Add(obj);
end;
procedure TForm1.butDisplayClick(Sen
var i: integer;
begin
memo1.Clear;
for i := 0 to (myList.Count-1) do begin
memo1.Lines.Add( TmyObjType(myList.Items[i]
end;
end;
procedure TForm1.butRemoveClick(Send
begin
delArrayItem( StrToInt(Edit1.Text) );
end;
end.
ASKER
Nuice, thanks :-)
ASKER
type
TmyObjType = class
Name : String;
constructor Create(S: string);
end;
-------------------------- ---------- --------
will this work with records?
TmyObjType = class
Name : String;
constructor Create(S: string);
end;
--------------------------
will this work with records?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Well done, top effort!
thank you, i'm glad i could be of help
procedure delArrayItem(Index: Integer);
begin
if Index > High(aArray) then Exit;
if Index < Low(aArray) then Exit;
if Index = High(aArray) then begin
SetLength(aArray, Length(aArray) - 1);
Exit;
end;
Finalize( aArray[Index] );
System.Move( aArray[Index +1], aArray[Index], (Length(aArray) - Index - 1) * SizeOf(string) + 1);
SetLength(aMenus, Length(aArray) - 1);
end;