GLBasic forum

Main forum => Bug Reports => Topic started by: mentalthink on 2012-Jul-02

Title: FOREACH and For n to X, question
Post by: mentalthink on 2012-Jul-02
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...




Title: Re: FOREACH and For n to X, question
Post by: kanonet on 2012-Jul-02
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.
Title: Re: FOREACH and For n to X, question
Post by: MrTAToad on 2012-Jul-03
FOREACH is used to access an array in a loop - using the FOR variable is just an extra use for the variable...
Title: Re: FOREACH and For n to X, question
Post by: mentalthink on 2012-Jul-03
Thanks Kano and MrT  :nw: :nw:
Title: Re: FOREACH and For n to X, question
Post by: hardyx on 2012-Jul-03
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
Title: Re: FOREACH and For n to X, question
Post by: mentalthink on 2012-Jul-03
HI hardyx thanks , nice trick!!!
Title: Re: FOREACH and For n to X, question
Post by: Slydog on 2012-Jul-03
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

Title: Re: FOREACH and For n to X, question
Post by: mentalthink on 2012-Jul-04
Hi Slydog very good too... thanks!!!
Title: Re: FOREACH and For n to X, question
Post by: MrTAToad on 2012-Jul-04
Or have an id variable...
Title: Re: FOREACH and For n to X, question
Post by: Crivens on 2012-Jul-04
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
Title: Re: FOREACH and For n to X, question
Post by: kanonet on 2012-Jul-04
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)
Title: Re: FOREACH and For n to X, question
Post by: Crivens on 2012-Jul-04
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