Thread overview
foreach and changing the aggregate's values?
Mar 26, 2005
AEon
Mar 26, 2005
Ben Hinkle
Mar 26, 2005
AEon
March 26, 2005
Just double checking I am not doing something bad, without knowing it:

char[][] glb.Ban;
glb.Ban[0] = "player\"";
glb.Ban[1] = "UnnamedPlayer\"";
glb.Ban[2] = "Padawan\"";

I did not actually init glb.Ban this way, but the data it contains is correct:

<code>
// ***The aggregate itself must not be resized, reallocated, free'd,
// reassigned or destructed while the foreach is iterating over the
// elements.

foreach(int i, char[] ban; glb.Ban)
{
	int joker = 0;
	if( ban[0] == '\"' )		// "abc, remove first "
	{
		joker += 1;
		glb.Ban[i] = ban[1..$].dup;
	}
	if( glb.Ban[i][$-1] == '\"' )	// abc", remove last "
	{
		joker += 2;
		glb.Ban[i] = glb.Ban[i][0..$-1].dup;
	}
	glb.banJoker[i] = joker;	// Remember the compare mode
}
</code>

Now from first reading the documentation, see *** comment, I should bot be able to change "aggregate itself".

If I understand it correctly though I am not actually changing the aggregat glb.Ban itself, but the values of the aggregat, e.g. glb.Ban[i]. So this is the reason the above works?

The documentation has this example:

<code>
int[] a;
int[] b;
foreach (int i; a)
{
    a = null;		// error
    a.length += 10;	// error
    a = b;		// error
    a[i] = 3;		// ***added, is not mentioned, but should work?!
}
a = null;		// ok
</code>

AEon
March 26, 2005
> Now from first reading the documentation, see *** comment, I should not be able to change "aggregate itself".
>
> If I understand it correctly though I am not actually changing the aggregat glb.Ban itself, but the values of the aggregat, e.g. glb.Ban[i]. So this is the reason the above works?

What you are doing should be ok but it seems cleaner to use inout:
  foreach(inout char[] ban; glb.Ban) {
   ...modify ban if needed ...
  }
instead of using the index i into the original glb.Ban.


March 26, 2005
Ben Hinkle wrote:
>>Now from first reading the documentation, see *** comment, I should not be able to change "aggregate itself".
>>
>>If I understand it correctly though I am not actually changing the aggregat glb.Ban itself, but the values of the aggregat, e.g. glb.Ban[i]. So this is the reason the above works?
> 
> 
> What you are doing should be ok but it seems cleaner to use inout:
>   foreach(inout char[] ban; glb.Ban) {
>    ...modify ban if needed ...
>   }
> instead of using the index i into the original glb.Ban.

ahh... I had been wondering when I would ever need inout... so this way I can change the current ban, and thus change the original glb.Ban[].

Indeed that would be neater to do.

AEon