## digitalmars.D.learn - Multidimensional foreach

- Simen kjaeraas (6/6) Dec 17 2009 I have a function that returns an N-dimensional array, where N is a
- Simen kjaeraas (64/68) Dec 18 2009 I wrote this implementation. Now, to get some meaningful indices
- Bill Baxter (23/33) Dec 18 2009 I think you need to explain more what you are hoping to accomplish.
- Simen kjaeraas (10/47) Dec 18 2009 I started out with no particular plan to this, but have arrived at wanti...

I have a function that returns an N-dimensional array, where N is a template parameter. Now I want to run a foreach loop through each element of this array. Is there a known and tested way to do this, or should I write my own templates to do it? -- Simen

Dec 17 2009

Simen kjaeraas <simen.kjaras gmail.com> wrote:I have a function that returns an N-dimensional array, where N is a template parameter. Now I want to run a foreach loop through each element of this array. Is there a known and tested way to do this, or should I write my own templates to do it?I wrote this implementation. Now, to get some meaningful indices out of it. Do D2's ranges even support that? Oh, and I probably need to rewrite it in terms of an index instead of slices to get that working. Bah. Ideas? Comments? Death threats? template ArrayBaseType( T ) { alias T ArrayBaseType; } template ArrayBaseType( T : U[], U ) { alias ArrayBaseType!( U ) ArrayBaseType; } template MultiDimRange( T ) { alias T MultiDimRange; } struct MultiDimRange( T : U[][], U ) { T arr; MultiDimRange!( U[] ) subRange; this( T arg ) { arr = arg; subRange = arg[ 0 ]; } void opAssign( T arg ) { arr = arg; subRange = arg[ 0 ]; } bool empty( ) { return ( arr.length <= 1 ) && subRange.empty; } ArrayBaseType!( T ) front( ) { assert( !empty, "Called front on empty range." ); if ( subRange.empty ) { typeof( subRange ) tmp = arr[ 1 ]; return tmp.front( ); } else { return subRange.front( ); } } ArrayBaseType!( T ) popFront( ) { assert( !empty, "Called popFront on empty range." ); ArrayBaseType!( T ) result; if ( subRange.empty ) { if ( arr.length <= 1 ) { throw new Exception( "Argh!" ); } arr = arr[ 1..$ ]; subRange = arr[0]; } result = front( ); subRange.popFront( ); return result; } } MultiDimRange!( T ) multiDimRange( T )( T args ) { return MultiDimRange!( T )( args ); } -- Simen

Dec 18 2009

On Fri, Dec 18, 2009 at 5:17 AM, Simen kjaeraas <simen.kjaras gmail.com> wrote:Simen kjaeraas <simen.kjaras gmail.com> wrote:I think you need to explain more what you are hoping to accomplish. In general there are two ways to store multidimensional data: 1) jagged - with arrays of arrays. This is the method directly supported by D arrays. With this accessing each element requires as many indirections as there are dimensions. But for large arrays, this is more friendly to memory use because the data doesn't have to be in one huge contiguous chunk 2) rectangular - with indexing into a chunk of memory. This method is directly supported by some languages like C#, but not D. Accessing each element requires just one indirection but a bit of offset computation. Very large arrays may have trouble fitting in available memory. (See this very old proposal for adding them to D: http://homepages.uni-regensburg.de/~nen10015/documents/D-multidimarray.html) Generally if your plan is to do math on these arrays, method 2 is better supported by existing math libraries. So what do you plan to do with these? You may be better off implementing a rectangular style multi-dim array type than trying to use D's built-in. Or look at the multi-dim array types written by Fawzi or myself. --bbI have a function that returns an N-dimensional array, where N is a template parameter. Now I want to run a foreach loop through each element of this array. Is there a known and tested way to do this, or should I write my own templates to do it?I wrote this implementation. Now, to get some meaningful indices out of it. Do D2's ranges even support that? Oh, and I probably need to rewrite it in terms of an index instead of slices to get that working. Bah. Ideas? Comments? Death threats?

Dec 18 2009

On Fri, 18 Dec 2009 19:49:31 +0100, Bill Baxter <wbaxter gmail.com> wrote:On Fri, Dec 18, 2009 at 5:17 AM, Simen kjaeraas <simen.kjaras gmail.com> wrote:I started out with no particular plan to this, but have arrived at wanting to make a range that facilitates "deep foreach" - that is, enumerate all ranges recursively. This way, it doesn't matter whether one wants to use a jagged or rectangular array. (except of course possibly for speed) btw, is there currently a way to support foreach( index, element; range ){} syntax for ranges? I can't seem to find any documentation on how to get the index. -- SimenSimen kjaeraas <simen.kjaras gmail.com> wrote:I think you need to explain more what you are hoping to accomplish. In general there are two ways to store multidimensional data: 1) jagged - with arrays of arrays. This is the method directly supported by D arrays. With this accessing each element requires as many indirections as there are dimensions. But for large arrays, this is more friendly to memory use because the data doesn't have to be in one huge contiguous chunk 2) rectangular - with indexing into a chunk of memory. This method is directly supported by some languages like C#, but not D. Accessing each element requires just one indirection but a bit of offset computation. Very large arrays may have trouble fitting in available memory. (See this very old proposal for adding them to D: http://homepages.uni-regensburg.de/~nen10015/documents/D-multidimarray.html) Generally if your plan is to do math on these arrays, method 2 is better supported by existing math libraries. So what do you plan to do with these? You may be better off implementing a rectangular style multi-dim array type than trying to use D's built-in. Or look at the multi-dim array types written by Fawzi or myself. --bbI have a function that returns an N-dimensional array, where N is a template parameter. Now I want to run a foreach loop through each element of this array. Is there a known and tested way to do this, or should I write my own templates to do it?I wrote this implementation. Now, to get some meaningful indices out of it. Do D2's ranges even support that? Oh, and I probably need to rewrite it in terms of an index instead of slices to get that working. Bah. Ideas? Comments? Death threats?

Dec 18 2009