Some Basic Array Questions

I have an array with 1000 items.  Every few seconds a new item is stuffed into the array.  I only want to keep the last 1000 items.

Is there a way to simply push a new item into the array, allowing the oldest one to fall off?  Meaning I would have to shift all of them each time a new item is added.  So if we are at 1000 items, then item number 1 gets deleted... number 2 becomes number 1, 3 becomes 2, etc.. all the way to number 1000 which moves to 999 to make room for the new number 1000.



Having asked this, is this the best way to do this?
LVL 4
PalamedesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

moorhouselondonCommented:
The best way is to treat the array as a circular buffer.  Have a function which stores the pointer to the current position of the buffer, when it gets to 1000, it wraps around to 1 again.

public
var
  bufptr:integer;


function circinc(i:integer):integer;
begin
if i=1000 then
  i:=1
else
  i:=i+1;
circinc:=i;
end;


somearray[bufptr]:=some new data;
bufptr:=circinc(bufptr);
somearray[bufptr]:=some more new data;

If you want to list out all the items in the array, you work back from the location pointed to by bufptr back to 1, then from 1000 back to bufptr+1.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TheRealLokiSenior DeveloperCommented:
If you only want to use the first item, then this sounds like a Queue (first in, first out)

uses contnrs;

var
  myqueue: TQueue;
 then you can push an item onto the end, and pop an item from the front.


alternatively. You could use a TList
var mylist: TList;

mylist := TList.create;

mylist.add( anobject )

while mylist.count > 1000 do
begin
    //free your object)
    //then
    mylist.delete(0)
end;

this keeps only 1000 items in the list.
0
Drunkard_EnglishmanCommented:
could you not use the move procedure to move all the records at once, and then change the last one?

a quick little example:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const

  ArrLength = 10;

var
  Form1: TForm1;
  Arr: array[0..ArrLength - 1] of Byte;
  ArrPntr: Integer = 0;
  x: Integer = 0;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if x <> 255 then Inc(x) else x := 0;
  if ArrPntr >= ArrLength then begin
    ArrPntr := ArrLength - 1;
    Move(Arr[1], Arr[0], (ArrLength - 1) * SizeOf(Byte));
  end;
  Arr[ArrPntr] := x;
  inc(ArrPntr);
  Caption := IntToStr(Arr[0]) + ', ' + IntToStr(Arr[1]) + ', ' + IntToStr(Arr[2]) + ', ' + IntToStr(Arr[3]) + ', ' + IntToStr(Arr[4]) + ', ' + IntToStr(Arr[5]) + ', ' + IntToStr(Arr[6]) + ', ' + IntToStr(Arr[7]) + ', ' + IntToStr(Arr[8]) + ', ' + IntToStr(Arr[9]);
end;

end.

this would only work with fixed sized data, so long strings would mess things up...
but it would beat moving through the list and moving things manually
0
moorhouselondonCommented:
As is often the case with these things, there is a trade-off between speed of execution and ease of coding.  The concept of not moving anything, but simply pointing to the head of the array is going to be faster.   The only things that need to be thought about are

(1) what happens when I get to the end of the array? (wrap around to the first item) and
(2) what happens when I look at an array that is not fully populated with 'events' (you initialise the array to start off with)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.