www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - multiSort for sorting AA by value

reply "Chris" <wendlec tcd.ie> writes:
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?
Apr 21 2015
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Apr 21 2015
next sibling parent "Chris" <wendlec tcd.ie> writes:
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!
Apr 21 2015
prev sibling parent "Chris" <wendlec tcd.ie> writes:
Maybe something like bearophile's example should go into the 
documentation of std.algorithm.sorting.multiSort. It's a common 
enough thing in programming.
Apr 21 2015