Lazy caching map()?

aliak something at something.com
Sat Mar 10 20:54:16 UTC 2018


On Friday, 9 March 2018 at 19:41:46 UTC, H. S. Teoh wrote:
> Today I found myself needing a lazy, caching version of map() 
> on an array.  More precisely, given an array `T[] src` of 
> source data and a function func(T) that's pretty expensive to 
> compute, return an object `result` such that:
>
> - result[i] == func(src[i]), for 0 ≤ i < src.length.
>
> - If result[j] is never actually used, func(src[j]) is never 
> invoked
>   (lazy).
>
> - If result[j] is referenced multiple times, a cached value is 
> returned
>   after the first time, i.e., the result of func(src[j]) is 
> cached, and
>   func(src[j]) is never invoked more than once.
>
> I couldn't figure out how to build this using Phobos 
> primitives, so I wrote my own implementation of it.  Pretty 
> simple, really, it's just a wrapper struct that lazily 
> initializes an array of Nullable!T and lazily populates it with 
> func(j) when opIndex(j) is invoked, and just returns the cached 
> value if opIndex(j) has been invoked before.
>
> Can this be done using current Phobos primitives?
>
>
> T

Unless I'm misunderstanding your requirements, are you looking 
for std.functionl.memoize?

auto fun(int a) {
     writeln("here");
     return a + 1;
}

void main() {
     auto a = [1, 2, 3];
     auto b = a.map!(memoize!fun);

     writeln(b[1]);
     writeln(b[1]);
     writeln(b[1]);
}

will print "here" just once.


More information about the Digitalmars-d mailing list