On 21.12.17 08:41, Jonathan M Davis wrote: > I would think that it would make a lot more sense to simply put the whole > thing in an array than to use memoize. e.g. > > auto arr = iota(1, 5).map!parse().array(); thats also possible, but i wanted to make use of the laziness ... e.g. if i then search over the flattened stuff, i do not have to parse the 10th file. i replaced joiner by a primitive flatten function like this: #!/usr/bin/env rdmd -unittest unittest { import std.stdio; import std.range; import std.algorithm; import std.string; import std.functional;
auto parse(int i) { writeln("parsing %s".format(i)); return [1, 2, 3]; } writeln(iota(1, 5).map!(parse)); writeln("-------------------------------"); writeln((iota(1, 5).map!(parse)).joiner); writeln("-------------------------------"); writeln((iota(1, 5).map!(memoize!parse)).joiner); writeln("-------------------------------"); writeln((iota(1, 5).map!(parse)).flatten); } auto flatten(T)(T input) { import std.range; struct Res { T input; ElementType!T current; this(T input) { this.input = input; this.current = this.input.front; advance(); } private void advance() { while (current.empty) { if (input.empty) { return; } input.popFront; if (input.empty) { return; } current = input.front; } } bool empty() { return current.empty; } auto front() { return current.front; } void popFront() { current.popFront; advance(); } } return Res(input); } void main() {} With this implementation my program behaves as expected (parsing the input data only once).