Jump to content
Joe Sansalone

For loop does NOT go to the max

Recommended Posts

Hi,

I've encountered something weird.  Delphi 10.4.2

I loop through the items in a list.

But also may add to that list in the loop.

Thus, extend the loop iterations.

 

var

list: TStringList;

 

for i := 0 to list.count-1 do 

begin

  // whatever processing

  list.append('another item');

end

 

PROBLEM:  the loop does not continue past the initial count.

 

I'm guessing this is a BUG?

 

Help,

Joe

 

 

 

 

Share this post


Link to post

Ranges of for loop counter are calculated once loop starts and won't change later. You'll either have to add another for loop inside or use another kind of loop (while, until + manual counter check and increment)

  • Like 3

Share this post


Link to post
13 minutes ago, Joe Sansalone said:

Hi,

I've encountered something weird.  Delphi 10.4.2

I loop through the items in a list.

But also may add to that list in the loop.

Thus, extend the loop iterations.

Ouch. Are you sure you want to do this? How are you going to ensure that your loop terminates when you keep adding items inside the loop?

 

Consider

list.count-1

to be a constant while the loop is executed. This ensures termination.
If you really want to change the list content while iterating over the list, use a while loop and ensure termination yourself.

Share this post


Link to post

"For purposes of controlling the execution of the loop, the expressions initialValue and finalValue are evaluated only once, before the loop begins."

 

You can use a 'while' statement to force the evaluation of the final value on every iteration.

i := 0
while i < list.count do

 

Share this post


Link to post
Quote

PROBLEM:  the loop does not continue past the initial count.

 

I'm guessing this is a BUG?

Most people consider this a feature. 

 

Append list elsewhere; Keep track of List count and start count at a lastProcessed count to reduce processing.

 

 

     

 

   

 

 

 

Share this post


Link to post
3 hours ago, Joe Sansalone said:

I see the benefit of For loop only evaluating once at initial.

 

 

This shows way mentioned to extend for..loop functionality.   

procedure TForm19.Button1Click(Sender: TObject);
var
  needsProcessed, startProcess: integer;
  LList: TList<integer>;
  s,r: string;
begin
  LList := TList<integer>.Create;
  try
    LList.AddRange([0,1,2,3,4,5]);
    needsProcessed := LList.Count; //process everything first time.
    
    Repeat
      startProcess := LList.Count - Needsprocessed;
      needsProcessed := 0;

      for var ii := startProcess to pred(LList.count) do
        begin                      //   ^  LList.Last would increase here!
           if ((LList.List[ii] mod 2) = 0) then
           begin
             inc(needsProcessed);
             r := ' even  ';
             with LList do add(Last + 1);
           end else r := ' odd  ';
           s := s + LList.List[ii].ToString + r + #13#10;
        end;
     until  (LList.count > 150) or (needsProcessed = 0);
     showMessage(s);
  finally
    LList.Free;
  end;
end;

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×