How do you iterate "vertically" over a 2-D array?

Stanislav Blinov stanislav.blinov at gmail.com
Tue Oct 9 12:04:31 UTC 2018


On Tuesday, 9 October 2018 at 10:52:47 UTC, Chris Katko wrote:
> I have a 2-D array:
>
> 1 - Is there a way to foreach vertically through that? (that 
> is, rotated 90 degrees from the usual iteration.)
>
> 2 - Is there a way to send that "vertical slice" to a function?

Not built-in in the language, no.

> I'm working on an RLE encoding function and I need both 
> vertical and horizontal strips. It just occurred to me that the 
> problem is essentially the same, if you can "transpose" the 
> matrix.

It may be the same on paper, but not in memory.

> Oh geez, did I just realize what I need? some sort of matrix 
> transpose function? I found this post;
>
> The problem is though, even if I use [][], instead of [5][5] 
> (or try using his conversion function), I can call 
> transposed... but I can't call my function with it!
>
> void run_rle3(int [] a){/*...*/}
>
> 	run_rle3(data[0]); //works
> 	run_rle3(data.transposed[0]); //nope [see error below]
> 	run_rle3(data[0].transposed); //nope (didn't expect this to)
> 	run_rle3((data.transposed)[0]); //nope [see error below]
>
> Error: function dmap.run_rle3 (int[] a) is not callable using 
> argument types (Transversal!(int[][], cast(TransverseOptions)0))

That's because your `run_rle3` function takes an `int[]`, which 
is a contiguous slice of ints. `transposed` does not return an 
`int[]`, it returns a lazy range (i.e. a struct with a range 
interface). Moreover, the range that `transposed` returns isn't 
even random-access, even though the source may be.
If you don't need random access and are just iterating over all 
elements, you can just change the signature of `run_rle3` to:

void run_rle3(R)(auto ref R a) { /* ... */ }

However, I'd first think hard about doing this. Iterating 
"vertically" you essentially skip (N-1) elements on each 
iteration, elements that would still be pulled into the CPU cache 
only to be ignored. If you're going to be iterating over every 
column this way, it may be more efficient to just eagerly 
transpose the whole array and use it as an array without any 
extra "transposed" abstractions.


More information about the Digitalmars-d-learn mailing list