[Issue 5550] std.range.enumerate()

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Jul 13 14:55:02 PDT 2012


http://d.puremagic.com/issues/show_bug.cgi?id=5550



--- Comment #4 from bearophile_hugs at eml.cc 2012-07-13 14:54:58 PDT ---
A well implemented enumerate() seems useful to avoid one of my recurrent D
bugs. This is a simplified example to show the bug. I have to create a matrix
like this:

0 10 20 30
0 11 21 31
0 12 22 32


There are many ways to inizialize a matrix like that, this is one way, but it's
not complete:


import std.stdio;
void main() {
    auto M = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
    foreach (r, row; M)
        foreach (c, ref item; row)
            item = c * 10 + r;
    writefln("%(%s\n%)", M);
}


It outputs:

[0, 10, 20, 30]
[1, 11, 21, 31]
[2, 12, 22, 32]


To complete the algorithm, that is to not touch the first column, I can use
just a slice in the second foreach, to not touch the first column:


import std.stdio;
void main() {
    auto M = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
    foreach (r, row; M)
        foreach (c, ref item; row[1 .. $])
            item = c * 10 + r;
    writefln("%(%s\n%)", M);
}


But this introduces the bug:

[0, 0, 10, 20]
[0, 1, 11, 21]
[0, 2, 12, 22]


Slicing 'row' from the second item I avoid to write on the first cells of each
row, but the 'c' index doesn't get sliced, it starts from zero still. One
correct version needs to increment c by one in the formula:

import std.stdio;
void main() {
    auto M = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
    foreach (r, row; M)
        foreach (c, ref item; row[1 .. $])
            item = (c + 1) * 10 + r;
    writefln("%(%s\n%)", M);
}


Another solution is to ignore the c==0:

    foreach (r, row; M)
        foreach (c, ref item; row)
            if (c != 0)
                item = c * 10 + r;


A well implemented enumerate() is one way to avoid that problem (other
solutions are possible), now 'c' gets sliced, so it doesn't start from zero:


import std.stdio;
void main() {
    auto M = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
    foreach (r, row; M)
        foreach (c, ref item; enumerate(row)[1 .. $])
            item = c * 10 + r;
    writefln("%(%s\n%)", M);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list