www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why does std.container.array does not work with foraech( i, a; array )

reply ParticlePeter <ParticlePeter gmx.de> writes:
Which of the op(Index) operators is responsible for enabling this 
kind of syntax?
Would it be possible to get it work with UFCS or would I have to 
wrap the array?
May 29 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Sunday, May 29, 2016 07:14:12 ParticlePeter via Digitalmars-d-learn wrote:
 Which of the op(Index) operators is responsible for enabling this
 kind of syntax?
 Would it be possible to get it work with UFCS or would I have to
 wrap the array?
std.container.array.Array works with foreach via ranges. foreach(e; myContainer) { } gets lowered to foreach(e; myContainer[]) { } which in turn gets lowered to something like for(auto r = myContainer[]; !r.empty; r.popFront()) { auto e = r.front; } Ranges do not support indices with foreach, and that's why you're not able to get the index with foreach and Array. However, if you use std.range.lockstep, you can wrap a range to get indices with foreach. e.g. foreach(i, e; lockstep(myContainer[])) { } http://dlang.org/phobos/std_range.html#.lockstep - Jonathan M Davis
May 29 2016
next sibling parent Mithun Hunsur <me philpax.me> writes:
On Sunday, 29 May 2016 at 09:07:07 UTC, Jonathan M Davis wrote:
 On Sunday, May 29, 2016 07:14:12 ParticlePeter via 
 Digitalmars-d-learn wrote:
 [...]
std.container.array.Array works with foreach via ranges. foreach(e; myContainer) { } gets lowered to foreach(e; myContainer[]) { } which in turn gets lowered to something like for(auto r = myContainer[]; !r.empty; r.popFront()) { auto e = r.front; } Ranges do not support indices with foreach, and that's why you're not able to get the index with foreach and Array. However, if you use std.range.lockstep, you can wrap a range to get indices with foreach. e.g. foreach(i, e; lockstep(myContainer[])) { } http://dlang.org/phobos/std_range.html#.lockstep - Jonathan M Davis
I'd say that std.range.enumerate is more indicative of intent: http://dlang.org/phobos/std_range.html#enumerate
May 29 2016
prev sibling parent ParticlePeter <ParticlePeter gmx.de> writes:
On Sunday, 29 May 2016 at 09:07:07 UTC, Jonathan M Davis wrote:
 On Sunday, May 29, 2016 07:14:12 ParticlePeter via 
 Digitalmars-d-learn wrote:
 Which of the op(Index) operators is responsible for enabling 
 this
 kind of syntax?
 Would it be possible to get it work with UFCS or would I have 
 to
 wrap the array?
std.container.array.Array works with foreach via ranges. foreach(e; myContainer) { } gets lowered to foreach(e; myContainer[]) { } which in turn gets lowered to something like for(auto r = myContainer[]; !r.empty; r.popFront()) { auto e = r.front; } Ranges do not support indices with foreach, and that's why you're not able to get the index with foreach and Array. However, if you use std.range.lockstep, you can wrap a range to get indices with foreach. e.g. foreach(i, e; lockstep(myContainer[])) { } http://dlang.org/phobos/std_range.html#.lockstep - Jonathan M Davis
Thanks, due to your answer I found a way which is even better for me. I pimped the Array containers with some UFCS functions anyway, one of them returns the array data as a slice and this works nicely with that foreach variant as well auto data( T )( Array!T array ) { if( array.length == 0 ) return null; return (&array.front())[ 0..array.length ]; } // this works now foreach( i, a; someArrayContainer.data ) { ... } - PP
May 29 2016