?
Solved

Remove item from dynamic array

Posted on 2007-09-28
15
Medium Priority
?
379 Views
Last Modified: 2010-04-05
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?

0
Comment
Question by:wildzero
  • 6
  • 5
  • 2
  • +2
15 Comments
 
LVL 5

Expert Comment

by:xr1140
ID: 19983245
i'm using this :


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;
0
 
LVL 10

Expert Comment

by:dinilud
ID: 19983336
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:Integer;
                          Del_IndexList:array of Integer; DelCount:Integer):Integer;
   Function IsInDel_IndexList(idx:Integer):Boolean;
     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]:=Source[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)-DeleteArray(X,length(X),[3,4,5],3));
  DisplayArray;
end;

end.
0
 
LVL 19

Expert Comment

by:MerijnB
ID: 19983438
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.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 14

Assisted Solution

by:Pierre Cornelius
Pierre Cornelius earned 300 total points
ID: 19990801
In my opinion, the best solution is using a TList or descendant of...
0
 
LVL 19

Assisted Solution

by:MerijnB
MerijnB earned 100 total points
ID: 19991064
I totally agree with you there
0
 
LVL 10

Author Comment

by:wildzero
ID: 19993719
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
0
 
LVL 5

Expert Comment

by:xr1140
ID: 19994038
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;
0
 
LVL 10

Author Comment

by:wildzero
ID: 19994048
Is a record classed as an object?
How would I got about adding/editing a record on a list?

(points upped)
0
 
LVL 5

Expert Comment

by:xr1140
ID: 19994202

here is the code for TList usage

http://rapidshare.com/files/59601470/_tmp__TList.rar
0
 
LVL 5

Expert Comment

by:xr1140
ID: 19994381
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(Sender: 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(Sender: TObject);
begin
  delArrayItem( StrToInt(Edit1.Text) );
end;

end.
0
 
LVL 10

Author Comment

by:wildzero
ID: 19994390
Nuice, thanks :-)
0
 
LVL 10

Author Comment

by:wildzero
ID: 19994398
type
  TmyObjType = class
    Name : String;
    constructor Create(S: string);
  end;
--------------------------------------------
will this work with records?

0
 
LVL 5

Accepted Solution

by:
xr1140 earned 1600 total points
ID: 19994495
here is the code with records



uMain.pas
===================


unit uMain;

interface

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

type
  PmyRec = ^myRec;
  myRec = record
    Name: 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}

procedure delArrayItem(Index: Integer);
var
  myRecord: PmyRec;
begin

  if Index > myList.Count then Exit;
  if Index < 0 then Exit;

  myRecord := myList.Items[Index];

  myList.Delete(Index);
  Dispose(myRecord);

end;


procedure TForm1.butAddClick(Sender: TObject);
var
  myRecord: PmyRec;
begin
  if myList = nil then begin
    myList := TList.Create;

  end;

  New(myRecord);
  myRecord^.Name := 'Item with index - ' + IntToStr(myList.Count);
  myList.Add(myRecord);

end;

procedure TForm1.butDisplayClick(Sender: TObject);
var
  i: integer;
  myRecord: PmyRec;
begin
  memo1.Clear;

  for i := 0 to (myList.Count-1) do begin
    myRecord := myList.Items[i];
    memo1.Lines.Add( myRecord^.Name );
  end;

end;

procedure TForm1.butRemoveClick(Sender: TObject);
begin
  delArrayItem( StrToInt(Edit1.Text) );
end;

end.
0
 
LVL 10

Author Comment

by:wildzero
ID: 19994499
Well done, top effort!
0
 
LVL 5

Expert Comment

by:xr1140
ID: 19994706

thank you, i'm glad i could be of help
0

Featured Post

Become an Android App Developer

Ready to kick start your career in 2018? Learn how to build an Android app in January’s Course of the Month and open the door to new opportunities.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Enter Foreign and Special Characters Enter characters you can't find on a keyboard using its ASCII code ... and learn how to make a handy reference for yourself using Excel ~ Use these codes in any Windows application! ... whether it is a Micr…
Planning to migrate your EDB file(s) to a new or an existing Outlook PST file? This video will guide you how to convert EDB file(s) to PST. Besides this, it also describes, how one can easily search any item(s) from multiple folders or mailboxes…
Suggested Courses
Course of the Month8 days, 15 hours left to enroll

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question