how to get top N distinct elements from range?

bearophile bearophileHUGS at lycos.com
Fri Mar 8 17:36:49 PST 2013


With this modified filter (that caches _input.front) it seems to 
work:


import std.stdio, std.range, std.algorithm, std.traits, 
std.random;

struct FilterResult2(alias pred, Range) {
     import std.traits: ForeachType;

     Range _input;
     ForeachType!Range rFront;

     this(Range r) {
         _input = r;

         while (!_input.empty) {
             this.rFront = _input.front;
             if (pred(this.rFront))
                 break;
             _input.popFront();
         }
     }

     @property bool empty() { return _input.empty; }

     void popFront() {
         do {
             _input.popFront();
             if (_input.empty)
                 break;
             this.rFront = _input.front;
             if (pred(this.rFront))
                 break;
         } while (true);
     }

     @property auto ref front() {
         return this.rFront;
     }
}

FilterResult2!(pred, Range) filter2(alias pred, Range)(Range rs) {
     return FilterResult2!(pred, Range)(rs);
}


auto distinct(Range)(Range r)
if (isInputRange!Range) {
     bool[ForeachType!Range] mySet;

     return r.filter2!((k) {
         if (k in mySet)
             return false;
         mySet[k] = true;
         return true;
     });
}

void main() {
     100.iota.map!(_ => uniform(0, 
10)).distinct.array.sort.writeln;
}


Is it a good idea to replace std.algorithm.filter with something 
like that filter2 (plus some missing methods)?

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list