Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the index of an item in a "for in" loop?

Tags:

loops

delphi

The following code works, but it is not as clean/general as the for..in loop.

fInports: TArray<TMyClass>

for i:= low(fInPorts) to high(fInPorts) do begin
  Port:= fInPorts[i];
  Port.Left:= ARect.Left;  
  Port.Top:= ARect.Top + (Height div (NrInPorts+1)) * (i+1);
end; {for i}

The for..in loop is much cleaner, but does not allow me to see which item is being accessed.

for Port in fInPorts do begin
  Port.Left:= ARect.Left;  
  Port.Top:= ARect.Top + (Height div (NrInPorts+1)) * index;  
  //how do I get the index? -------------------------^^^^^^^
end; {for}

How do I know which item within the Array is currently being processed by the for..in loop?

like image 839
Johan Avatar asked Jan 10 '23 09:01

Johan


2 Answers

The whole point of a for in loop is that the index should not be relevant. It's the enumerator's decision which order it will return the elements in. The enumerator could change the internal order that the elements are returned and the code using it should still work. The controls could be sorted by type, name, etc. Obviously in the case of an array the compiler magic returns the elements of the array in order but with other enumerators that will not necessarily be the case.

If you want the index for your positioning, then as Jerry said, you would have to create an index and use that in your code. If it was a TList you could cheat and use IndexOf but that would be counter productive from a performance point of view.

Personally I tend to only use for in loops sparingly but that's just because I am old school. I am too much of a control freak.

like image 183
Graymatter Avatar answered Jan 17 '23 18:01

Graymatter


You cannot get the index when using a for in loop. Pretty much the entire point of for in loops is that they serve up items rather than indices. However, your code does not need the index at all.

LLeft := ARect.Left;
LTop := ARect.Top;
for Port in fInPorts do begin
  Port.Left:= LLeft;  
  Port.Top:= LTop + Height div (NrInPorts+1);
  LTop := Port.Top;
end;

It is true that enumerators are entitled to serve up items in any order. However, it is quite reasonable to assume that the enumerators for arrays and lists serve up the items in a specific order. That is in order of increasing index.

like image 36
David Heffernan Avatar answered Jan 17 '23 16:01

David Heffernan