Joe Sansalone 6 Posted August 3, 2021 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
Fr0sT.Brutal 900 Posted August 3, 2021 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) 3 Share this post Link to post
luebbe 26 Posted August 3, 2021 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
timfrost 78 Posted August 3, 2021 "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
Joe Sansalone 6 Posted August 3, 2021 I didn't realize For loop evaluates only once. Thanks for everyone's comments. I'll use a While loop. Share this post Link to post
Pat Foley 51 Posted August 3, 2021 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
Joe Sansalone 6 Posted August 3, 2021 I see the benefit of For loop only evaluating once at initial. Share this post Link to post
Pat Foley 51 Posted August 3, 2021 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