Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I update a TList while iterating with a for-in loop?

I am trying to learn about Generics in Delphi but have a very basic problem with TList.

I have successfully created a list integers and filled it with 1000 odd numbers. I want to change every number on the list that is divisible by 3 to 0. I thought that I could do something like this.

For I in Mylist Do
Begin
  If (I mod 3)= 0 Then
    I:=0;
End;

This clearly does not work so I would appreciate someone explaining what will.

like image 202
user3861642 Avatar asked Nov 30 '25 03:11

user3861642


1 Answers

You are using a for..in loop, which uses a read-only enumerator. This code:

For I in Mylist Do
Begin
  If (I mod 3) = 0 Then
    I := 0;
End;

Is actually doing this:

Enum := Mylist.GetEnumerator;
while Enum.MoveNext do
Begin
  I := Enum.Current;
  If (I mod 3) = 0 Then
    I := 0;
End;

That is why you cannot modify the list contents in a for..in loop. You have to use an older-style for loop instead, using the TList<T>.Items[] property to access the values:

For I := 0 to Mylist.Count-1 Do
Begin
  If (Mylist[I] mod 3) = 0 Then
    Mylist[I] := 0;
End;

Update: to then remove the zeros, you can do this:

For I := Mylist.Count-1 downto 0 Do
Begin
  If Mylist[I] = 0 Then
    Mylist.Delete(I);
End;

Or, do it in the initial loop so you don't need a second loop:

For I := Mylist.Count-1 downto 0 Do
Begin
  If (Mylist[I] mod 3) = 0 Then
    Mylist.Delete(I);
End;
like image 114
Remy Lebeau Avatar answered Dec 02 '25 15:12

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!