从 Smalltalk 中的字典中获取具有最大值的键
Get key with largest value from a dictionary in Smalltalk
我正在使用字典,其中键是字符串,值是整数。我怎样才能从这个字典中得到具有最大值的键?
我知道可以使用 associationsDo:
方法来遍历键和值,但我不知道如何获得最大值。
| countDict |
countDict := Dictionary new.
...
countDict associationsDo: [ :k :v | ??? ]
这里有一种方法可以按照您的想法进行:
| 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
,而应使用 Bag
。 Bag
的实例表示对象的集合,每个对象可能有多次出现。示例:
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: 'John' ----> 2
Bag
内部会有 countDict
之类的 Dictionary
,但对于您的模型来说,Bag
比 Dictionary
更能揭示您的意图因为您只需要 add:
个元素而无需计算它们; Bag
会为您完成。
有了 Bag
你的计算就变成了
bag occurrencesOf: bag asSet max
发送asSet
的原因是为了避免在每个值上迭代多次,如果我们简单地输入bag max
就会发生这种情况。这个更简单的代码也可以工作,但是考虑到 max
使用 do:
迭代并且 Bag
通过对元素的每次出现重复块的评估来实现 do:
,这个解决方案效率会降低。
更好的方法是在 Bag
中重新实现 max
(和 min
),以便每个元素迭代一次。这类似于我们上面的代码,它遵循您最初的想法 (associationsDo: [
...)。但是,让我们将此细节留作 reader.
的练习。
无论如何,如果我们在Bag
中重新实现max
,代码会立刻变得简单高效:
bag occurrencesOf: bag max
另一个很好的方法:
(countDict associations detectMax: #value) key
我正在使用字典,其中键是字符串,值是整数。我怎样才能从这个字典中得到具有最大值的键?
我知道可以使用 associationsDo:
方法来遍历键和值,但我不知道如何获得最大值。
| countDict |
countDict := Dictionary new.
...
countDict associationsDo: [ :k :v | ??? ]
这里有一种方法可以按照您的想法进行:
| 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
,而应使用 Bag
。 Bag
的实例表示对象的集合,每个对象可能有多次出现。示例:
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: 'John' ----> 2
Bag
内部会有 countDict
之类的 Dictionary
,但对于您的模型来说,Bag
比 Dictionary
更能揭示您的意图因为您只需要 add:
个元素而无需计算它们; Bag
会为您完成。
有了 Bag
你的计算就变成了
bag occurrencesOf: bag asSet max
发送asSet
的原因是为了避免在每个值上迭代多次,如果我们简单地输入bag max
就会发生这种情况。这个更简单的代码也可以工作,但是考虑到 max
使用 do:
迭代并且 Bag
通过对元素的每次出现重复块的评估来实现 do:
,这个解决方案效率会降低。
更好的方法是在 Bag
中重新实现 max
(和 min
),以便每个元素迭代一次。这类似于我们上面的代码,它遵循您最初的想法 (associationsDo: [
...)。但是,让我们将此细节留作 reader.
无论如何,如果我们在Bag
中重新实现max
,代码会立刻变得简单高效:
bag occurrencesOf: bag max
另一个很好的方法:
(countDict associations detectMax: #value) key