[Issue 5550] New: std.range.enumerate()

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Feb 8 17:04:03 PST 2011


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

           Summary: std.range.enumerate()
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody at puremagic.com
        ReportedBy: bearophile_hugs at eml.cc


--- Comment #0 from bearophile_hugs at eml.cc 2011-02-08 17:01:39 PST ---
I suggest to add an enumerate() to Phobos std.range module. An alternative name
is count().

enumerate() is a simple function, it takes one iterable and returns an iterable
of (index, item) pairs:

>>> list(enumerate("abcd"))
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]


A second optional argument allows to define a start value different from zero:

>>> list(enumerate("abcd", 3))
[(3, 'a'), (4, 'b'), (5, 'c'), (6, 'd')]


This is an example usage of Python2.6 enumerate():

>>> comp = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1]
>>> [i for i,b in enumerate(comp) if not b]
[2, 3, 5, 7, 11, 13, 17, 19]
>>> comp = comp[2:]
>>> comp
[0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1]
>>> [i for i,b in enumerate(comp, 2) if not b]
[2, 3, 5, 7, 11, 13, 17, 19]


Here the input 'comp' is a list of bits (booleans) produced by a Sieve of
Eratosthenes, that represents the composite numbers. The desired output (a
sequence of primes) is a list of indexes where the value b is false, so it's
prime.

This is a D2 translation in procedural style:

import std.stdio;
void main() {
    auto comp = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0,
1];
    int[] result;
    foreach (i, p; comp)
        if (!p)
            result ~= i;
    writeln(result);

    comp = comp[2..$];
    result.length = 0;
    foreach (i, p; comp)
        if (!p)
            result ~= i + 2;
    writeln(result);
}


A translation in functional style:

import std.stdio, std.algorithm, std.range;
void main() {
    auto comp = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0,
1];
    auto result1 = map!q{a[0]}(filter!q{!a[1]}(zip(iota(comp.length), comp)));
    writeln(result1);

    comp = comp[2..$];
    auto result2 = map!q{a[0]+2}(filter!q{!a[1]}(zip(iota(comp.length),
comp)));
    writeln(result2);
}


An enumerate() allows to write simpler code:

import std.stdio, std.algorithm, std.range;
void main() {
    auto comp = [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0,
1];
    auto result1 = map!q{a[0]}(filter!q{!a[1]}(enumerate(comp)));
    writeln(result1);

    comp = comp[2..$];
    auto result2 = map!q{a[0]}(filter!q{!a[1]}(enumerate(comp, 2)));
    writeln(result2);
}


zip(iota(foo.length), foo) becomes even worse when the iterable foo is lazy and
doesn't define a length:
zip(iota(walkLength(foo)), foo)

-- 
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