Thread overview
How would I sort an associative array by value?
Jun 29, 2012
ixid
Jun 29, 2012
Timon Gehr
Jun 29, 2012
ixid
Sep 06, 2013
Ludovit Lucenic
Sep 06, 2013
H. S. Teoh
Sep 07, 2013
Ludovit Lucenic
June 29, 2012
Or more generally does D have a library function so I can sort one array based on sorting the contents of another? I don't want to just sort the values alone, the associated keys would need to move with them. I can think of ways of doing it myself, just wondering if there's an elegant way built in.
June 29, 2012
On 06/29/2012 07:52 PM, ixid wrote:
> Or more generally does D have a library function so I can sort one array
> based on sorting the contents of another?

sort!"a[0]<b[0]"(zip(basedOnThis, alsoSortThis));

This sorts both ranges in-place based on the contents of the first range.
June 29, 2012
Thank you!
September 06, 2013
On Friday, 29 June 2012 at 18:00:06 UTC, Timon Gehr wrote:
> On 06/29/2012 07:52 PM, ixid wrote:
>> Or more generally does D have a library function so I can sort one array
>> based on sorting the contents of another?
>
> sort!"a[0]<b[0]"(zip(basedOnThis, alsoSortThis));
>
> This sorts both ranges in-place based on the contents of the first range.

Hello,

I have a similar problem, having statistics per class instance. How would I print out the statistics sorted ?

struct TestTuple {
    ...
}

int[TestTuple] stats;

foreach (test, stat; ??) {
    writeln(test, " = ", stat);
}

Please, what comes in ?? ? Your proposal sort!"a[0]<b[0]"(stats) does not compile in this place.

Thank you in advance,
Ludovit
September 06, 2013
On Fri, Sep 06, 2013 at 08:58:48AM +0200, Ludovit Lucenic wrote:
> On Friday, 29 June 2012 at 18:00:06 UTC, Timon Gehr wrote:
> >On 06/29/2012 07:52 PM, ixid wrote:
> >>Or more generally does D have a library function so I can sort one array based on sorting the contents of another?
> >
> >sort!"a[0]<b[0]"(zip(basedOnThis, alsoSortThis));
> >
> >This sorts both ranges in-place based on the contents of the first range.
> 
> Hello,
> 
> I have a similar problem, having statistics per class instance. How would I print out the statistics sorted ?
> 
> struct TestTuple {
>     ...
> }
> 
> int[TestTuple] stats;
> 
> foreach (test, stat; ??) {
>     writeln(test, " = ", stat);
> }
> 
> Please, what comes in ?? ? Your proposal sort!"a[0]<b[0]"(stats)
> does not compile in this place.
[...]

You mean you want to sort the stats.keys by the values they are mapped to?

What about:

	import std.array, std.algorithm, std.stdio, std.typecons;

	// I don't know what your original struct was, this one is just
	// for example.
	struct TestTuple {
		string name;
	}

	void main() {
		int[TestTuple] stats;

		// Make some sample data for testing
		stats[TestTuple("test1")] = 10;
		stats[TestTuple("test2")] = 4;
		stats[TestTuple("test3")] = 8;
		stats[TestTuple("test4")] = 11;

		// Sort by stats. If you want to sort by name instead,
		// change "a[0] < b[0]" to "a[1] < b[1]".
		foreach (t; stats.keys
				.map!((a) => tuple(stats[a], a))
				.array
				.sort!((a,b) => a[0] < b[0]))
		{
			auto stat = t[0];
			auto test = t[1];
			writeln(test, " = ", stat);
		}
	}

The built-in AA's are inherently unordered, so they cannot be sorted directly. You have to explicitly put the keys / values into an array and sort that.


T

-- 
Computers shouldn't beep through the keyhole.
September 07, 2013
On Friday, 6 September 2013 at 16:57:09 UTC, H. S. Teoh wrote:
> You mean you want to sort the stats.keys by the values they are mapped
> to?
>
Yes, this exactly I wanted to do.
> What about:
>
> 	import std.array, std.algorithm, std.stdio, std.typecons;
> 	
> 	// I don't know what your original struct was, this one is just
> 	// for example.
> 	struct TestTuple {
> 		string name;
> 	}
> 	
> 	void main() {
> 		int[TestTuple] stats;
> 	
> 		// Make some sample data for testing
> 		stats[TestTuple("test1")] = 10;
> 		stats[TestTuple("test2")] = 4;
> 		stats[TestTuple("test3")] = 8;
> 		stats[TestTuple("test4")] = 11;
> 	
> 		// Sort by stats. If you want to sort by name instead,
> 		// change "a[0] < b[0]" to "a[1] < b[1]".
> 		foreach (t; stats.keys
> 				.map!((a) => tuple(stats[a], a))
> 				.array
> 				.sort!((a,b) => a[0] < b[0]))
> 		{
> 			auto stat = t[0];
> 			auto test = t[1];
> 			writeln(test, " = ", stat);
> 		}
> 	}
>
> The built-in AA's are inherently unordered, so they cannot be sorted
> directly. You have to explicitly put the keys / values into an array and
> sort that.
>
>
> T

Thank you, your code makes perfect sense. I'm still kinda discovering beauty of D.

Ludovit