range chunks

Adrian Matoga epi at atari8.info
Fri Aug 6 14:50:54 PDT 2010


On 2010-08-06 19:33, Philippe Sigaud wrote:
> 2010/8/6 Adrian Matoga <epi at atari8.info <mailto:epi at atari8.info>>
> 
>     Hi,
> 
>     Is there any off the shelf solution for iterating over a range by
>     chunks?
> 
> 
> None that I know of.
> 
>     (should substitute [1, 2, 3], [4, 5, 6], [7, 8, 9], [10] for chunk
>     in subsequent iterations)
> 
> 
> As a data point, why do you think it should produce [10] and not stop at 
> [7,8,9]?

By an analogy to taking a file by chunks. The other case also occured to 
me but I simply thought I could imagine more situations in which I need 
the whole input range to be exhausted, including remainder.

> Here is what I cooked, it's still a bit rough around the edges. It has 
> an optional step argument, to see how many elements to jump.
> 
> import std.range;
> struct Chunks(R) if (isInputRange!R)
> {
>     R range;
>     size_t n; // chunk size
>     size_t step; // how many elements to jump
> 
>     bool empty() @property { return range.empty;}
>     ElementType!R[] front() @property { return array(take(range, n));} 
> // inefficient if you call front() many times in a row
>     void popFront() @property { popFrontN(range, step);}
> 
>     static if (hasLength!R)
>         size_t length() @property { return (range.length+step-1)/step;}
> }
> 
> Chunks!R chunks(R)(R range, size_t n) if (isInputRange!R)
> {
>     return Chunks!R(range, n, n); // default is step == n
> }
> 
> Chunks!R chunks(R)(R range, size_t n, size_t step) if (isInputRange!R)
> {
>     return Chunks!R(range, n, step);
> }
>  
> 

Thank you very much!

And yes, I also think it should be included in std.range (actually 
before posting the question I was almost sure I could find it there ;)).

Adrian


More information about the Digitalmars-d mailing list