Comment #0 by bearophile_hugs — 2014-02-02T08:53:12Z
I suggest to add to std.range a range designed to flatten a given n-dimensional range.
A simple usage example:
int[][] mat = [[1, 2], [3, 4]];
auto mu = mat.flatten.uniq;
std.range.flatten should take a range, range of ranges, range of range of ranges, etc, and yield the scanned items.
A possible signature:
Flatten flatten(ScanType scan = ScanType.rows(), Range, Targs...)(Range input, int maxDepth=-1, Targs args);
Where maxDepth tells it a what depth to stop, defaulting to -1 that means to reach the bottom.
ScanType can be:
enum ScanType {
rows,
columns,
bidirectionalRows,
bidirectionalColumns,
}
Later more scans can be added:
enum ScanType {
rows,
columns,
bidirectionalRows,
bidirectionalColumns,
zigZag,
hammingCurve,
zCurve,
rectBlocked
}
args is used by ScanArgs.rectBlocked, to specify the nx and ny of a 2D block. The blocked scan is useful because it's a cache-friendly scan for large 2D arrays.
Ideally flatten should yield references of the items, so you can increase all matrix items by 1 with code like:
int[][][] mat = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]];
foreach (ref x; mat.flatten)
x++;
Comment #1 by jack — 2016-01-18T06:40:45Z
This can be superseded by using std.experimental.ndslice and byElement
Comment #2 by greensunny12 — 2016-08-30T01:23:02Z
> This can be superseded by using std.experimental.ndslice and byElement
nslice only works on RandomAccesRanges, so I believe this is still a valid request.