sortOn: sorts range of aggregates by member name(s)

via Digitalmars-d digitalmars-d at puremagic.com
Wed Nov 5 13:29:18 PST 2014


On Wednesday, 5 November 2014 at 20:50:00 UTC, Nordlöw wrote:
> On Wednesday, 5 November 2014 at 16:54:38 UTC, Marc Schütz 
> wrote:
>> My idea was something along these lines (untested):
>>
>>    template extractorFun(alias extractor) {
>>        static if(is(typeof(extractor) : string)) {
>>            auto ref extractorFun(T)(auto ref T a) {
>>                mixin("with(a) { return " ~ extractor ~ "; }");
>>            }
>>        } else {
>>            alias extractorFun = extractor;
>>        }
>>    }
>>
>>    alias fn = extractorFun!extractor;
>>    r.sort!((a, b) => (fn(a) < fn(b)));
>
> Thanks, I'll use this!
>
> Still, is it even possible to extend extractor to become 
> variadic or do I have to write a number of explicit overloads
>
> 1: void sortBy(alias xtr, R)(R r)
> 2: void sortBy(alias xtrA, alias xtrB, R)(R r)
> 3: void sortBy(alias xtrA, alias xtrB, alias xtrC, R)(R r)
> etc
>
> ?

Again untested:

private alias makePredicate(alias xtr) =
     (a, b) => (extractorFun!xtr(a) < extractorFun!xtr(b));

auto sortBy(extractors..., R)(R r) {
     alias preds = staticMap!(makePredicate, extractors);
     return r.sort!preds;
}

(Variadic template parameters also accept aliases.)


More information about the Digitalmars-d mailing list