www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ranges.chunks and map! does not work

reply Andre Pany <andre s-e-a-p.de> writes:
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);
}

The exact error message is (this line is 3 times repeated):
app1.d(12): Error: no [] operator overload for type Take!(Result)
app1.d(12): Error: no [] operator overload for type Take!(Result)
app1.d(12): Error: no [] operator overload for type Take!(Result)
C:\SAPDevelop\D\dmd2\windows\bin\..\..\src\phobos\std\algorit
m\iteration.d(499):        instantiated from here: MapResult!(__lambda1,
Chunks!(Result))
app1.d(12):        instantiated from here: map!(Chunks!(Result))

Is it correct that I need to call ".map!(c => c.array)"?

Kind regards
André
Jul 05 2018
next sibling parent Timoses <timosesu gmail.com> writes:
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
Jul 05 2018
prev sibling next sibling parent Alex <sascha.orlov gmail.com> writes:
On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote:
 Is it correct that I need to call ".map!(c => c.array)"?

 Kind regards
 André
Well, no. It depends on how you define the formatting string. This would also work: ´´´ 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 => "%(%g,%)".format(c)) .join("\n"); writeln(content); } ´´´
Jul 05 2018
prev sibling parent reply vit <vit vit.vit> writes:
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);
 }

 The exact error message is (this line is 3 times repeated):
 app1.d(12): Error: no [] operator overload for type 
 Take!(Result)
 app1.d(12): Error: no [] operator overload for type 
 Take!(Result)
 app1.d(12): Error: no [] operator overload for type 
 Take!(Result)
 C:\SAPDevelop\D\dmd2\windows\bin\..\..\src\phobos\std\algorit
m\iteration.d(499):        instantiated from here: MapResult!(__lambda1,
Chunks!(Result))
 app1.d(12):        instantiated from here: map!(Chunks!(Result))

 Is it correct that I need to call ".map!(c => c.array)"?

 Kind regards
 André
roundRobin doesn't return RandomAccessRange => chunks doesn't return range of RandomAccessRange => Error: no [] operator overload try this: string content = roundRobin(timestamps, temperatures, pressures) .array .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n");
Jul 05 2018
parent Andre Pany <andre s-e-a-p.de> writes:
On Thursday, 5 July 2018 at 12:00:03 UTC, vit wrote:
 On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote:
 [...]
roundRobin doesn't return RandomAccessRange => chunks doesn't return range of RandomAccessRange => Error: no [] operator overload try this: string content = roundRobin(timestamps, temperatures, pressures) .array .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n");
Thanks a lot for all the answers. Kind regards Andre
Jul 05 2018