Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 07, 2006 suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
I often find my self doing something like this: <code> int i char[] arr; foreach(int j, c; arr) if(' ' == c) { i=j; // copy j out of foreach's scope break; } if(i < arr.length) { arr = arr.dup; // use copy of j foreach(inout c; arr[i..$]) if(' ' == c) c = '_'; } </code> In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i. <code> int i char[] arr; foreach(int i, c; arr) if(' ' == c) break; // i keeps the value from the last time through ... </code> Thoughts comments?? |
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | "BCS" <BCS@pathlink.com> wrote in message news:e67p90$rol$1@digitaldaemon.com... >I often find my self doing something like this: > > <code> > int i > char[] arr; > > foreach(int j, c; arr) > if(' ' == c) > { > i=j; // copy j out of foreach's scope > break; > } > > if(i < arr.length) > { > arr = arr.dup; > // use copy of j > foreach(inout c; arr[i..$]) > if(' ' == c) c = '_'; > } > </code> > > In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i. > > <code> > int i > char[] arr; > > foreach(int i, c; arr) > if(' ' == c) > break; > > // i keeps the value from the last time through > ... > </code> > > > Thoughts comments?? Wouldn't a function return serve a similar if not identical purpose? |
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ameer Armaly | On Wed, 7 Jun 2006 20:27:51 -0400, Ameer Armaly <ameer_armaly@hotmail.com> wrote:
> "BCS" <BCS@pathlink.com> wrote in message
> news:e67p90$rol$1@digitaldaemon.com...
>> I often find my self doing something like this:
>>
>> <code>
>> int i
>> char[] arr;
>>
>> foreach(int j, c; arr)
>> if(' ' == c)
>> {
>> i=j; // copy j out of foreach's scope
>> break;
>> }
>>
>> if(i < arr.length)
>> {
>> arr = arr.dup;
>> // use copy of j
>> foreach(inout c; arr[i..$])
>> if(' ' == c) c = '_';
>> }
>> </code>
>>
>> In this case it would be nice to be able to use a variable in the outer
>> scope as the index in the foreach, e.i.
>>
>> <code>
>> int i
>> char[] arr;
>>
>> foreach(int i, c; arr)
>> if(' ' == c)
>> break;
>>
>> // i keeps the value from the last time through
>> ...
>> </code>
>>
>>
>> Thoughts comments??
> Wouldn't a function return serve a similar if not identical purpose?
Requiring you to put the foreach in a function? Probably.
At the very least we need some way to indicate we want the behaviour as it really shouldn't use variables external to the foreach by default. eg.
int i;
char[] arr;
foreach(inout int i, c; arr) {}
or
foreach(inout i, c; arr) {}
or something. Something/anything to indicate the 'i' in the loop is the 'i' from outside the loop. Or, perhaps another block which is executed with the foreach variables when the loop doesn't terminate normally:
foreach(int i, c; arr) {
}
else {
//comes here if you use 'break' in foreach
//i, and c have the last values they had in the loop.
//what happens in the 'inout c' cases?
}
Regan
|
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | "Regan Heath" <regan@netwin.co.nz> wrote in message news:optasxzhwe23k2f5@nrage.netwin.co.nz... > On Wed, 7 Jun 2006 20:27:51 -0400, Ameer Armaly <ameer_armaly@hotmail.com> wrote: >> "BCS" <BCS@pathlink.com> wrote in message news:e67p90$rol$1@digitaldaemon.com... >>> I often find my self doing something like this: >>> >>> <code> >>> int i >>> char[] arr; >>> >>> foreach(int j, c; arr) >>> if(' ' == c) >>> { >>> i=j; // copy j out of foreach's scope >>> break; >>> } >>> >>> if(i < arr.length) >>> { >>> arr = arr.dup; >>> // use copy of j >>> foreach(inout c; arr[i..$]) >>> if(' ' == c) c = '_'; >>> } >>> </code> >>> >>> In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i. >>> >>> <code> >>> int i >>> char[] arr; >>> >>> foreach(int i, c; arr) >>> if(' ' == c) >>> break; >>> >>> // i keeps the value from the last time through >>> ... >>> </code> >>> >>> >>> Thoughts comments?? >> Wouldn't a function return serve a similar if not identical purpose? > > Requiring you to put the foreach in a function? Probably. > It just seems to me that if you want something to loop over a set and inform you of the stopping point, that's the natural place for a function, though I could be overlooking some corner cases. > At the very least we need some way to indicate we want the behaviour as it really shouldn't use variables external to the foreach by default. eg. > > int i; > char[] arr; > > foreach(inout int i, c; arr) {} > > or > > foreach(inout i, c; arr) {} > > or something. Something/anything to indicate the 'i' in the loop is the 'i' from outside the loop. Or, perhaps another block which is executed with the foreach variables when the loop doesn't terminate normally: > > foreach(int i, c; arr) { > } > else { > //comes here if you use 'break' in foreach > //i, and c have the last values they had in the loop. > //what happens in the 'inout c' cases? > } > > Regan |
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | On Wed, 07 Jun 2006 17:04:09 -0700, BCS wrote: > I often find my self doing something like this: > > <code> > int i > char[] arr; > > foreach(int j, c; arr) > if(' ' == c) > { > i=j; // copy j out of foreach's scope > break; > } > > if(i < arr.length) > { > arr = arr.dup; > // use copy of j > foreach(inout c; arr[i..$]) > if(' ' == c) c = '_'; > } > </code> > > In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i. > > <code> > int i > char[] arr; > > foreach(int i, c; arr) > if(' ' == c) > break; > > // i keeps the value from the last time through > ... > </code> > > Thoughts comments?? I see what you mean but have you tried this ... int i; char[] arr; foreach(int j, c; arr) if(' ' == c) { arr = arr.dup; foreach(inout c; arr[j..$]) if(' ' == c) c = '_'; break; } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 8/06/2006 11:12:32 AM |
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <cs4o03emrdkm$.b5qasiolumf7.dlg@40tude.net>, Derek Parnell says... >On Wed, 07 Jun 2006 17:04:09 -0700, BCS wrote: >> I often find my self doing something like this: [...] >> >> <code> >> int i >> char[] arr; >> >> foreach(int i, c; arr) >> if(' ' == c) >> break; >> >> // i keeps the value from the last time through >> ... >> </code> >> >> Thoughts comments?? > >I see what you mean but have you tried this ... > > int i; > char[] arr; > foreach(int j, c; arr) > if(' ' == c) > { > arr = arr.dup; > foreach(inout c; arr[j..$]) > if(' ' == c) c = '_'; > break; > } > That would work but its not vary expandable. Try doing that for five or six loops. The proposed solution is just a lot cleaner, even in the two loop case. Or how about doing that with something like: char[] arr; int j=0, i, skip; do { foreach(inout i, c; arr[j..$]) if(‘ ' == c) break; // do something and continue j+=(i+skip); }while(i != arr.length) |
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ameer Armaly | In article <e67qth$ugk$1@digitaldaemon.com>, Ameer Armaly says... > > >"BCS" <BCS@pathlink.com> wrote in message news:e67p90$rol$1@digitaldaemon.com... >>I often find my self doing something like this: >> >> <code> >> int i >> char[] arr; >> >> foreach(int j, c; arr) >> if(' ' == c) >> { >> i=j; // copy j out of foreach's scope >> break; >> } >> >> if(i < arr.length) >> { >> arr = arr.dup; >> // use copy of j >> foreach(inout c; arr[i..$]) >> if(' ' == c) c = '_'; >> } >> </code> >> >> In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i. >> >> <code> >> int i >> char[] arr; >> >> foreach(int i, c; arr) >> if(' ' == c) >> break; >> >> // i keeps the value from the last time through >> ... >> </code> >> >> >> Thoughts comments?? >Wouldn't a function return serve a similar if not identical purpose? > > Yes, but that would require putting the foreach in a function. If it needs to access local variables then it needs to be a nested function and therefore could results in a lot of lookup by pointer. Also there is the added function call overhead associated with it. If the code is performance critical all of these are bad things. |
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | What's weird to me is if I do this: void main() { int i; char[] arr = "abc def"; foreach( i, c; arr ) { printf( "%i\n", i ); if(' ' == c) break; } printf( "\n%i\n", i ); } Then the output is: 0 1 2 3 0 So the code compiles without a type for i in the foreach, but rather than use the instance of i in the surrounding scope a local value is used instead. The spec isn't clear on what should happen here, but I would have guessed that the final value displayed would be 3, not 0. Sean |
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> What's weird to me is if I do this:
>
> void main()
> {
> int i;
> char[] arr = "abc def";
>
> foreach( i, c; arr )
> {
> printf( "%i\n", i );
> if(' ' == c)
> break;
> }
> printf( "\n%i\n", i );
> }
>
> Then the output is:
>
> 0
> 1
> 2
> 3
>
> 0
>
> So the code compiles without a type for i in the foreach, but rather than use the instance of i in the surrounding scope a local value is used instead. The spec isn't clear on what should happen here, but I would have guessed that the final value displayed would be 3, not 0.
>
>
> Sean
It creates a new scope, just like for loops:
int i = 5;
for (int i = 0; i < 3; ++i)
writefln(i); // 0 to 2
writefln(i); // 5
I don't know about the spec's opinion, but this is how it has always worked,
both with for and foreach, and I have a lot of code that relies on this behaviour.
The "inout" suggested elsewhere in the thread by Regan Heath seems like a good solution to me.
|
June 08, 2006 Re: suggested change to foreach index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deewiant | Deewiant wrote:
> Sean Kelly wrote:
>> What's weird to me is if I do this:
>>
>> void main()
>> {
>> int i;
>> char[] arr = "abc def";
>>
>> foreach( i, c; arr )
>> {
>> printf( "%i\n", i );
>> if(' ' == c)
>> break;
>> }
>> printf( "\n%i\n", i );
>> }
>>
>> Then the output is:
>>
>> 0
>> 1
>> 2
>> 3
>>
>> 0
>>
>> So the code compiles without a type for i in the foreach, but rather
>> than use the instance of i in the surrounding scope a local value is
>> used instead. The spec isn't clear on what should happen here, but I
>> would have guessed that the final value displayed would be 3, not 0.
>>
>>
>> Sean
>
> It creates a new scope, just like for loops:
>
> int i = 5;
> for (int i = 0; i < 3; ++i)
> writefln(i); // 0 to 2
> writefln(i); // 5
Yes, but my example was equivalent to this (I thought):
int i = 5;
for (i = 0; i < 3; ++i)
writefln(i); // 0 to 2
writefln(i); // 2
ie, the lack of a type makes the "i=0" an assignment, not a declaration with an initializer. The i from the surrounding scope is used. I expected foreach to behave the same way, but apparently it doesn't.
Sean
|
Copyright © 1999-2021 by the D Language Foundation