Help with Ranges
schveiguy at gmail.com
Sun Jul 26 14:56:35 UTC 2020
On 7/26/20 3:10 AM, Charles wrote:
> Suppose I have the following line of code where arr is an array,
> doSomething is some predicate that does a lot of processing on each
> element, sort must come after the mapping, and there are more operations
> done to the range after sort:
> arr.map!doSomething.sort. ...;
> Sort fails to instantiate because the range it's receiving doesn't
> support element swapping. This may and might be resolved by calling array:
> arr.map!doSomething.array.sort. ...;
> However, this might trigger an allocation, and there's still more to do!
> Is there something I'm missing with regards to ranges that could help me
> make the first line work without using array, or is it more of an issue
> with my code's design?
That is what you need to do.
A map that returns an lvalue would be sortable, but you would be sorting
the processed elements, and probably not the original elements.
I have found this handy tool quite useful in my code where I need a
// creates a concrete range (std.container.array.Array range) out of the
// original range that is eagerly fetched, and then can be processed,
// allocating extra garbage on the heap.
auto concreteRange(Range)(Range r)
import std.range : ElementType;
import std.container.array : Array;
Slicing an Array will keep the reference count correctly, and destroy
the memory automatically after you're done using it. So it's perfect for
temporary arrays in pipelining.
More information about the Digitalmars-d-learn