Thread overview | ||||||
---|---|---|---|---|---|---|
|
December 17, 2009 Multidimensional foreach | ||||
---|---|---|---|---|
| ||||
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
|
December 18, 2009 Re: Multidimensional foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | 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 |
December 18, 2009 Re: Multidimensional foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | On Fri, Dec 18, 2009 at 5:17 AM, Simen kjaeraas <simen.kjaras@gmail.com> wrote: > 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? 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. --bb |
December 18, 2009 Re: Multidimensional foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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: >> 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? > > 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. > > --bb 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. -- Simen |
Copyright © 1999-2021 by the D Language Foundation