Working with ranges
Paul Backus
snarwin at gmail.com
Wed May 26 15:59:50 UTC 2021
On Wednesday, 26 May 2021 at 13:58:56 UTC, Elmar wrote:
> This example will not compile:
>
> ```
> auto starts = arr[0..$].stride(2);
> auto ends = arr[1..$].stride(2);
> randomNumbers[] = ends[] - starts[];
> ```
>
> Because `[]` is not defined for the Result range. Is there a
> standard wrapper function which wraps an elementwise `[]`
> operator implementation around a range?
Something like this ought to work:
```d
import std.range: zip;
import std.algorithm: map, copy;
/// calls `fun` with the members of a struct or tuple as arguments
alias apply(alias fun) = args => fun(args.tupleof);
zip(starts, ends)
.map!(apply!((start, end) => end - start))
.copy(randomNumbers[]);
```
In general, array operators like `[]` only work with arrays. The
Result ranges you get from `stride` are not arrays, so to work
with them, you need to use range algorithms like the ones in
`std.range` and `std.algorithm`.
(Some ranges actually do support `[]`, but it is never
guaranteed. You can check for such support with
[`std.range.primitives.hasSlicing`][1].)
If you would prefer a more convenient syntax for working with
things like strided arrays, I recommend giving [libmir][2] a
look. It's a high-quality collection of D libraries for numerical
and scientific computing.
[1]:
https://phobos.dpldocs.info/std.range.primitives.hasSlicing.html
[2]: https://www.libmir.org/
More information about the Digitalmars-d-learn
mailing list