FOREACH and For n to X, question

Previous topic - Next topic

mentalthink

Hi I have a doubt whit for and foreach... when you have an Array whit Types and you make a For TO, you can show the variable of the for whit a print... Ex:

I can use n_Item for shot the counter
for n_Item=0 to len(array[])-1
  array[n_Item].x = n_Item * 10
  array[n_Item].y = n_Item * 10
  print n_Item    , 10, 10 *n_Item
next

but whit FOREACH
foreach n_Item in array[]
  n_Item.x = n_Item.x * 10
  n_Item.y = n_Item.y * 10

  print n_Item?¿ [not works,], 10, 10*
next

Thanks, I don´t know if it´s enough clear...





kanonet

As far as i know there is no way to get the index with FOREACH. You just can use a variable and INC it every loop, or use FOR-TO.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

MrTAToad

FOREACH is used to access an array in a loop - using the FOR variable is just an extra use for the variable...

mentalthink


hardyx

FOR... NEXT works with indexes (integers), and FOREACH works with the array elements, one in each round. You obtain a reference to each array element. In your example:

Code (glbasic) Select
foreach Item in array[]
  Item.x = Item.x * 10
  Item.y = Item.y * 10
  print Item.x + "," + Item.y, 10, 10
next

mentalthink

HI hardyx thanks , nice trick!!!

Slydog

#6
Or you can add a 'ToString()' method to your TYPE, such as:

Code (glbasic) Select
TYPE TVector
  x%
  y%

  FUNCTION ToString$:
    RETURN "TVector: " + self.x + ", " + self.y
  ENDFUNCTION

ENDTYPE


Then, using your example:

Code (glbasic) Select
FOREACH n_Item IN array[]
  n_Item.x = n_Item.x * 10
  n_Item.y = n_Item.y * 10

  PRINT n_Item.ToString$(), 10, 10
NEXT


This lets you customize how you want your TYPE details displayed, without hard coding it each time.

[Edit] But of course you still don't get access to the index, so you can't print on different lines based on the index.

[Edit2] Maybe we need a new command such as GETINDEX% for use ONLY in FOREACH statements, such as:
Code (glbasic) Select
FOREACH n_Item IN array[]
  n_Item.x = n_Item.x * 10
  n_Item.y = n_Item.y * 10

  PRINT n_Item.ToString$(), 10, 10 * GETINDEX
NEXT

My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

mentalthink

Hi Slydog very good too... thanks!!!

MrTAToad

Or have an id variable...

Crivens

QuoteOr have an id variable...
Yeah that's what I do incase I need it. Just before the DIMPUSH I do item.id=LEN(itemlist). Does the trick. 

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.

kanonet

But then you get problems if you use a DIMDEL.
(Ok you can decrease all later ids, but thats more work than just use FOR-To or INC an index inside FOREACH)
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Crivens

True but then I haven't had a reason to use a DIMDEL on an array I need to keep the ID on to be honest. The DIMDEL project I did really didn't need the ID. Normally it's just a nicety when you can process with FOREACH.

Possibly would be good to be able to have a proper ID. Like you can with VB6 collections. It's basically a key. So we could have the idea where you could assign all your items to an array, then if the array is configured for a key (obviously don't need the memory and CPU overhead for every array) you could assign a key of anything you like (no duplicates), and then access that item in the array at anytime by referencing that key.

So, for example, you could use DRAWSPRITE xsprite["hero"].spriteid,xsprite["hero"].x,sprite["hero"].y rather than DRAWSPRITE xsprite[hero].spriteid,xsprite[hero].x,sprite[hero].y, which as you said could lose the correct hero pointer with a DIMDEL. Obviously the example could be replicated using FOREACH, but lets say you want to only show certain sprites in your array. Sure you could have a .visible tag, but you still process each item. Another array only full of keys for visible objects in your array would mean running through that array (and referencing your object array) would be a lot quicker. Obviously "a lot quicker" depends on what sort of algorithm is used to dig out an array element from a given key. Would be good though.

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.