Mosty Mostacho
Mosty Mostacho

Reputation: 43434

How to sort a Dictionary by values in Smalltalk?

I've got a Dictionary like this:

a PluggableDictionary(
    Rankable1->8.5
    Rankable2->9.0
)

I need just an OrderedCollection with the Rankable objects in descending order:

a OrderedCollection(
    Rankable2
    Rankable1
)

I noticed it is easy to sort by keys, but I found it a bit more difficult to sort by values. What is the smalltalk way of doing this?

Upvotes: 4

Views: 2255

Answers (4)

Tobias
Tobias

Reputation: 3110

If you can use Grease (eg, when using Seaside), you can probably use its GROrderedMultiMap. It is intended for small dictionaries with probably multiple values per key.

On a second note, probably you can swap key and value, and just send #asSortedCollection, like this:

(Dictionary newFrom: { 2 -> 'b' . 1-> 'a' }) 
    asSortedCollection "-->  a SortedCollection('a' 'b')"

(Tested in Squeak and Pharo)

Upvotes: 2

Travis Griggs
Travis Griggs

Reputation: 22252

If you're using VisualWorks, you can take advantage of SortFunction and Symbol>>value behavior to reduce all of that down to

(aDictionary associations sort: #value ascending) collect: #key

Upvotes: 2

Davorin Ruševljan
Davorin Ruševljan

Reputation: 4392

If you need one shot sorted collection in noncritical loop you might use something like this (uses pharo syntax to initialize example dictionary):

pd := PluggableDictionary newFromPairs: { 'a' . 2 . 'b' . 1 . 'c' . 3} . 

(pd associations asSortedCollection: [:x :y | x value < y value]) 
            collect: [:assoc | assoc key].

If you would need it more often, than you might consider introducing your own class that will keep this collection calculated.

Upvotes: 6

Mosty Mostacho
Mosty Mostacho

Reputation: 43434

Got it:

^ ((SortedCollection sortBlock: 
   [:association :otherAssociation | association value > otherAssociation value])
   addAll: theDictionary associations;
   yourself) collect: [:association | association key]

Upvotes: 1

Related Questions