从Smalltalk中的字典中获取具有最大值的密钥

JNe*_*ens 3 smalltalk pharo

我正在使用一个字典,其中键是字符串,值是整数.如何获得具有此字典中最大值的密钥?

我知道有一种associationsDo:方法可以用来迭代键和值,但我不知道如何获得最大值.

| countDict |
countDict := Dictionary new.
...
countDict associationsDo: [ :k :v | ??? ]
Run Code Online (Sandbox Code Playgroud)

Lea*_*lia 6

以下是按照您的想法执行此操作的方法:

| max largest |
max := nil.
countDict associationsDo: [:k :v |
  (max isNil or: [v > largest])
    ifTrue: [
      max := k.
      largest := v]].
^max
Run Code Online (Sandbox Code Playgroud)

这是另一种方式,更短但效率不高:

 countDict isEmpty ifTrue: [^nil].
 ^countDict keyAtValue: countDict max
Run Code Online (Sandbox Code Playgroud)

此外,如果你有一个countDict我怀疑它代表每个键的出现次数.如果是这种情况你不应该使用a Dictionary而是a Bag.Bag表示可能每次出现多次的对象集合的实例.例子:

names := Bag new.
people do: [:person | names add: person firstName].
Run Code Online (Sandbox Code Playgroud)

你最终可能会

2 occurrences of 'John'
1 occurrence of 'Paul'
4 occurrences of 'Ringo'
7 occurrences of 'George'

names occurrencesOf: 'Jon'  ---->  2
Run Code Online (Sandbox Code Playgroud)

Bag会在内部有一个countDict排序的Dictionary,而是你的模型Bag能更好地揭示你的意图不是Dictionary因为你只需要add:要素,而不必指望他们; 该Bag会为你做它.

随着Bag你的计算成为

bag occurrencesOf: bag asSet max
Run Code Online (Sandbox Code Playgroud)

发送的原因asSet是为了避免对每个值进行多次迭代,如果我们简单地放置就会发生这种情况bag max.这个更简单的代码也可以工作,但考虑到max迭代使用do:Bag实现,do:通过对每次出现的元素重复块的评估,这个解决方案的效率会降低.

更好的方法是重新实现max(和min)in,Bag以便每个元素迭代一次.这类似于我们上面的代码,它遵循了您最初的想法(associationsDo: [...).但是,让我们把这个细节作为读者的练习.

无论如何,如果我们重新implemnted maxBag,代码将变得简单而高效的一次:

 bag occurrencesOf: bag max
Run Code Online (Sandbox Code Playgroud)


Uko*_*Uko 5

另一种很好的方法来做到这一点:

(countDict associations detectMax: #value) key
Run Code Online (Sandbox Code Playgroud)