www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Sorted output from an associative array

reply FG <home fgda.pl> writes:
Let's say i have an array: int[string] wordCount.
How to print key:value pairs ordered by descending value?
Or generally how to to store wordCount in an array of structs or type tuples
for 
later sorting?

In Python I would use something like this:
sorted(wordCount.items(), key=lambda a: a[1], reverse=True).
Jan 30 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.vom> writes:
FG:

 Let's say i have an array: int[string] wordCount.
That's an associative array, and it's unsorted just like a Python dict. In Phobos there is a sorted tree, if you want, that keeps keys sorted.
 How to print key:value pairs ordered by descending value?
There are various solutions. A simple solution is to use a foreach to create an array of 2-tuples (key,value), and then use a schwartzsort to sort just according to values.
 Or generally how to to store wordCount in an array of structs 
 or type tuples for later sorting?
You don't use type tuples for that, just Phobos tuples. This code is not fast because it appends (untested): Tuple!(string, int)[] items; foreach (k, v; wordCount) items ~= tuple(k, v); items.schwartzSort!(it => it[1], "a < b")();
 In Python I would use something like this:
 sorted(wordCount.items(), key=lambda a: a[1], reverse=True).
In Python you use key=itemgetter(1). And in Python2 you use iteritems() for that. Unfortunately in D there is no byPair() because that ties druntime with std.typecons... Bye, bearophile
Jan 30 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
 Tuple!(string, int)[] items;
 foreach (k, v; wordCount)
     items ~= tuple(k, v);
 items.schwartzSort!(it => it[1], "a < b")();
A little tested: import std.stdio, std.algorithm, std.typecons; void main() { uint[string] wordCount = ["the":200, "val":100, "blue":1000]; auto items = new Tuple!(string, uint)[wordCount.length]; uint i = 0; foreach (k, v; wordCount) items[i++] = tuple(k, v); // avoided append items.schwartzSort!(it => it[1], "a < b")(); writeln(items); } Bye, bearophile
Jan 30 2013
parent FG <home fgda.pl> writes:
Thanks for showing me how to use tuples in this problem.

Just for the record, the sort comparison should be reversed: "a > b".
Jan 30 2013
prev sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 30 January 2013 at 15:43:21 UTC, FG wrote:
 Let's say i have an array: int[string] wordCount.
 How to print key:value pairs ordered by descending value?
 Or generally how to to store wordCount in an array of structs 
 or type tuples for later sorting?

 In Python I would use something like this:
 sorted(wordCount.items(), key=lambda a: a[1], reverse=True).
Basically, you have to extract and sort a third party data structure. what you can do is extract only the keys though, and sort them according to a specific pred. Then once your keys are sorted, you can re-obtain the value from the original AA. Examplea addapted from TDPL: //---- void main(string[] args) { int[string] freqs = ["a":1, "b":3 , "c":2]; // Print according to alphabet { string[] words = freqs.keys; sort(words); writeln("sorted by alphabet"); foreach (word; words) writefln("%6u\t%s", freqs[word], word); writeln(); } // Print according to frequency { string[] words = freqs.keys; sort!((a, b) { return freqs[a] > freqs[b]; })(words); writeln("sorted by frequency"); foreach (word; words) writefln("%6u\t%s", freqs[word], word); writeln(); } } //---- sorted by alphabet 1 a 3 b 2 c sorted by frequency 3 b 2 c 1 a //----
Jan 30 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 30 January 2013 at 16:22:37 UTC, monarch_dodra 
wrote:
 On Wednesday, 30 January 2013 at 15:43:21 UTC, FG wrote:
 Let's say i have an array: int[string] wordCount.
 How to print key:value pairs ordered by descending value?
 Or generally how to to store wordCount in an array of structs 
 or type tuples for later sorting?

 In Python I would use something like this:
 sorted(wordCount.items(), key=lambda a: a[1], reverse=True).
Basically, you have to extract and sort a third party data structure. what you can do is extract only the keys though, and sort them according to a specific pred. Then once your keys are sorted, you can re-obtain the value from the original AA.
Yes, as mentioned, you can use schartzsort for better performance. Even then though, depending on the size of your values, it may be smarter to sort only the keys.
Jan 30 2013