Thread overview
multiSort for sorting AA by value
Apr 21, 2015
Chris
Apr 21, 2015
bearophile
Apr 21, 2015
Chris
Apr 21, 2015
Chris
April 21, 2015
The following works great. It sorts an AA by value:

1. by frequency of word
2. by alphabetic order (if two or more words have the same value)

import std.stdio : writefln;
import std.algorithm.sorting : multiSort;

void main() {
  size_t[string] wcount = [
    "hamster":5,
    "zorro":80,
    "troll":90,
    "algorithm":80,
    "beer":80
  ];
  struct Word { string word; size_t count; }
  Word[] sorter;
  foreach (ref k, ref v; wcount)
    sorter ~= Word(k, v);
  assert(wcount.length == sorter.length);
  sorter.multiSort!("a.count > b.count", "a.word < b.word");
  assert(sorter[2].word == "beer");
  foreach (ref it; sorter)
    writefln("%s : %d", it.word, it.count);
}

I'm happy with it, but maybe there is a more concise implementation?
April 21, 2015
Chris:

> I'm happy with it, but maybe there is a more concise implementation?

This is a bit shorter and a bit better (writefln is not yet able to format tuples nicely):


void main() {
    import std.stdio: writeln;
    import std.algorithm.sorting: multiSort;
    import std.array: array;

    const size_t[string] wCount = [
        "hamster": 5,
        "zorro": 80,
        "troll": 90,
        "algorithm": 80,
        "beer": 80
    ];

    auto pairs = wCount.byKeyValue.array;
    assert(wCount.length == pairs.length);
    pairs.multiSort!(q{a.value > b.value}, q{a.key < b.key});
    assert(pairs[2].key == "beer");
    foreach (const ref it; pairs)
        writeln(it.key, ": ", it.value);
}


Bye,
bearophile
April 21, 2015
On Tuesday, 21 April 2015 at 11:46:24 UTC, bearophile wrote:
> Chris:
>
>> I'm happy with it, but maybe there is a more concise implementation?
>
> This is a bit shorter and a bit better (writefln is not yet able to format tuples nicely):
>
>
> void main() {
>     import std.stdio: writeln;
>     import std.algorithm.sorting: multiSort;
>     import std.array: array;
>
>     const size_t[string] wCount = [
>         "hamster": 5,
>         "zorro": 80,
>         "troll": 90,
>         "algorithm": 80,
>         "beer": 80
>     ];
>
>     auto pairs = wCount.byKeyValue.array;
>     assert(wCount.length == pairs.length);
>     pairs.multiSort!(q{a.value > b.value}, q{a.key < b.key});
>     assert(pairs[2].key == "beer");
>     foreach (const ref it; pairs)
>         writeln(it.key, ": ", it.value);
> }
>
>
> Bye,
> bearophile

Nice!
April 21, 2015
Maybe something like bearophile's example should go into the documentation of std.algorithm.sorting.multiSort. It's a common enough thing in programming.