I am using a Dictionary where the keys are strings and the values are integers. How can I get the key with the largest value out of this Dictionary?
I know there is the associationsDo:
method I can use to iterate over both keys and values, but I don't know how to get the maximum value.
| countDict |
countDict := Dictionary new.
...
countDict associationsDo: [ :k :v | ??? ]
Here is a way to do it following your idea:
| max largest |
max := nil.
countDict associationsDo: [:k :v |
(max isNil or: [v > largest])
ifTrue: [
max := k.
largest := v]].
^max
Here is another way, shorter but not very efficient:
countDict isEmpty ifTrue: [^nil].
^countDict keyAtValue: countDict max
Also, if you have a countDict
I suspect that it represents the number of occurrences of every key. If that is the case you shouldn't be using a Dictionary
but a Bag
. Instances of Bag
represent collections of objects which may have several occurrences each. Examples:
names := Bag new.
people do: [:person | names add: person firstName].
and you may end up with
2 occurrences of 'John'
1 occurrence of 'Paul'
4 occurrences of 'Ringo'
7 occurrences of 'George'
names occurrencesOf: 'John' ----> 2
The Bag
will internally have a countDict
sort of Dictionary
, but to your model a Bag
could reveal better your intention than a Dictionary
because you will only need to add:
elements without having to count them; the Bag
will do it for you.
With a Bag
your computation becomes
bag occurrencesOf: bag asSet max
The reason to send asSet
is to avoid iterating several times on every value, which would happen if we simply put bag max
. This simpler code will also work, but given that max
iterates using do:
and Bag
implements do:
by repeating the evaluation of the block for every occurrence of the element, this solution would be less efficient.
A better approach would be to re-implement max
(and min
) in Bag
so that each element is iterated once. This would be similar to the code that we have above which followed your initial idea (associationsDo: [
...). But let's leave the details of this as an exercise for the reader.
Anyway, if we re-implemnted max
in Bag
, the code would become simple and efficient at once:
bag occurrencesOf: bag max
Another nice way to do this:
(countDict associations detectMax: #value) key
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With