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