ranges.chunks and map! does not work

Timoses timosesu at gmail.com
Thu Jul 5 10:26:05 UTC 2018


On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote:
> Hi,
>
> the purpose of this code is to generate CSV based on 3 double 
> arrays.
> I wonder why map cannot directly use the result of the chunks 
> function.
>
> import std.experimental.all;
>
> void main()
> {
>     double[] timestamps = [1.1];
>     double[] temperatures = [2.2];
>     double[] pressures = [3.3];
>
>     string content = roundRobin(timestamps, temperatures, 
> pressures)
>         .chunks(3)
>         //.map!(c => c.array)
>         .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2]))
>         .join("\n");
>
>     writeln(content);
> }

I always find this kind of confusing as well. What kind of ranges 
are returned by functions handling ranges and returning another 
range?

It is clear what type of range can be passed by looking at the 
constraint for chunks[1]:
Chunks!Source chunks(Source)(Source source, size_t chunkSize)
if (isInputRange!Source);

It would be awesome to have something like and output constraint:
out(Output; isForwardRange!Output && 
isInputRange!(ElementType!Output))

or something similar to know what the function will return..

In your case it seems like the typeof(c.front) is not a random 
access range:
     auto c = roundRobin(timestamps, temperatures, pressures)
         .chunks(3);
     pragma(msg, isRandomAccessRange!(typeof(c.front)));
     // prints false

So you could do

     auto content = roundRobin(timestamps, temperatures, pressures)
         .evenChunks(timestamps.length)
         .map!(c =>
               c.map!(a => format("%.10g", a))
                .join(",")
               )
         .join("\n");

although there might be more elegant solutions.

[1]: https://dlang.org/phobos/std_range.html#chunks


More information about the Digitalmars-d-learn mailing list