Is there something like a consuming take?
Adam D. Ruppe
destructionator at gmail.com
Sat Jul 6 14:40:52 UTC 2019
On Saturday, 6 July 2019 at 14:12:36 UTC, berni wrote:
> Meanwhile I encountered, that take() sometimes consumes and
> sometimes not.
It depends on what you're passing.
So take is defined as just getting the first N elements from the
given range. So what happens next depends on what it is "taking"
from (I don't like the name "take" exactly because that implies,
well, taking. What the function really does is more like "view
into first N elements".
With input ranges, iterating over them consumes it implicitly, so
you could say that take *always* consumes input ranges (at least
once it gets iterated over).
But, it will frequently consume a copy of the range instead of
the one you have at the top level, since ranges are passed by
value.
If you want it to be seen outside, `ref` is the general answer.
You might find success with refRange in some cases.
http://dpldocs.info/experimental-docs/std.range.refRange.html
But if you are passing something with slicing, like a plain
array, take will never actually consume it, and instead just
slice the input, even if it is ref. This gets the view of those
first elements in cheaper way.
So going back to your original definition:
> I want to copy the first n items of a range to an array,
> removing these items from the range.
As far as I know, none of the std.range functions are defined to
do this.
I'd probably write your own that:
1) takes the range by ref so changes are visible outside
2) iterates over it with popFront
3) returns the copy
that should fulfill all the requirements. you could slightly
optimize arrays (or other hasSlicing things) like
int[] yourFunction(ref int[] arr, int n) {
auto ret = arr[0 .. n];
arr = arr[n .. $];
return ret;
}
that is, just slicing and consuming in one go for each side and
then you don't even have to actually copy it, just return the
slice.
More information about the Digitalmars-d-learn
mailing list