www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - foreach and changing the aggregate's values?

reply AEon <aeon2001 lycos.de> writes:
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
Mar 26 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
 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.
Mar 26 2005
parent AEon <aeon2001 lycos.de> writes:
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
Mar 26 2005