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

时间:2016-12-10 10:19:37

标签: smalltalk pharo

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

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

| countDict |
countDict := Dictionary new.
...
countDict associationsDo: [ :k :v | ??? ]

2 个答案:

答案 0 :(得分:6)

按照您的想法,这是一种方法:

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

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

 countDict isEmpty ifTrue: [^nil].
 ^countDict keyAtValue: countDict max

此外,如果您有countDict我怀疑它代表每个密钥的出现次数。如果是这种情况,则不应使用Dictionary,而应使用BagBag的实例表示可能每次出现多次的对象集合。例子:

names := Bag new.
people do: [:person | names add: person firstName].

你最终可能

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

names occurrencesOf: 'Jon'  ---->  2

Bag内部会有countDictDictionary,但对于您的模型,Bag可能会比Dictionary显示出更好的意图,因为您只需要add:个元素而不必计算它们; Bag将为您完成。

使用Bag计算成为

bag occurrencesOf: bag asSet max

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

更好的方法是在max中重新实现min(和Bag),以便每个元素迭代一次。这与我们上面的代码(associationsDo: [ ...)之后的代码类似。但是,让我们把这个细节作为读者的练习。

无论如何,如果我们在max中重新实现Bag,代码将立即变得简单有效:

 bag occurrencesOf: bag max

答案 1 :(得分:4)

另一种很好的方法:

(countDict associations detectMax: #value) key