The FOREACH command works well, its easy to use and cuts out all of that old BOUNDS/LEN+Local types stuff we had to do before but some commands kinda messes it up. DIMDEL for example. If you want to delete a variable, say from an array, using FOREACH, then you have to set up a counter and increment through the array, hand in hand with FOREACH, so that you can use "DIMDEL myarray, counter". The problem is that FOREACH has no mechanism to tell DIMDELL where it is in the list, exactly, with a numeric parameter that DIMDEL can use.
The loop counter for a FOREACH commend in the produced GLB 'C' is stored in the integer variable "foreachtmp". If this was exposed, say as a function ("HERE()" or whatever), then you could do this...
FOREACH tmp IN b[]
IF tmp.a = 80
DIMDEL b[], HERE()
NEXT
And to prove it already works, here is an INLINE hack of "foreachtmp" exposed...
TYPE mytype
a
FUNCTION foo:
ENDFUNCTION
ENDTYPE
GLOBAL b[] AS mytype
DIM b[10]
GLOBAL i%, n%
FOREACH tmp IN b[]
tmp.a = i%
i% = i% + 10
NEXT
n% = 0
FOREACH tmp IN b[]
PRINT tmp.a, 0 , n%
n% = n% + 10
NEXT
i% = 0
n% = 0
FOREACH tmp IN b[]
IF tmp.a = 0 OR tmp.a = 10 OR tmp.a = 90 OR tmp.a = 80
INLINE
i = --foreachtmp;
ENDINLINE
DIMDEL b[],i
ELSE
PRINT tmp.a, 20 , n%
ENDIF
n% = n% + 10
NEXT
n% = 0
FOREACH tmp IN b[]
PRINT tmp.a, 40 , n%
n% = n% + 10
NEXT
SHOWSCREEN
MOUSEWAIT
hmmm, what about using DELETE within a FOREACH loop? It's designed for deleting the current list element in FOREACH. So there's no need to use DIMDEL in this case.
FOREACH tmp IN b[]
IF tmp.a = 80
DELETE tmp
ENDIF
NEXT
Thanks for that Quentin,
Well DELETE would do but Its not always desirable for the code to jump back to the FOREACH after a DELETE, which is why I use DIMDEL.
Also, it would be nice to return a numeric 'pointer' to where you are, within an array being itterated with FOREACH, for various purposes.
Cheers,
Ian
Guess I can't see what exactly you're looking for :)
use FOR .. NEXT if you need to know the index of the current loop, FOREACH, if not. Or use a counter in FOREACH. Use CONTINUE if you don't want the rest of the code to be executed (e.g. after DELETE) or BREAK to leave the loop. What else is needed. Seems I can't follow your train of thought :doubt:
FOREACH tmp IN b[]
INC loop_cnt
IF tmp.a = 80
DELETE a // or DIMDEL b[], loop_cnt
CONTINUE
ENDIF
IF tmp.a > 100
BREAK
ENDIF
NEXT
Sorry if I am not clear, its sometimes hard to convey code into words. ;)
There is no option to continue after using a DELETE, as DELETE does an automatic CONTINUE whenever it is used.
This is one issue, getting the current index of a FOREACH would be advantageous for many other situations too.
Cheers,
Ian
QuoteThere is no option to continue after using a DELETE, as DELETE does an automatic CONTINUE whenever it is used.
The easiest way around it would be to setup a marker in a type that checks to see if an item needs deleting. If not, then you continue with some other code.
If 'foreachtmp' was exposed then there would be no need for work-arounds, for the DIMDEL situation and others.
I thought about that once, too. I'll see what I can do.