[英]How is ordered a Dictionary in Pharo?
Let's say we have a loop that enters Association
s to a Dictionary
in a clear order:假设我们有一个循环,它以明确的顺序将
Association
s 输入到Dictionary
中:
| d |
d := Dictionary new: 10.
1 to: 10 do: [ :i |
d add: i -> (i + 9 printStringBase: 20)
].
d
When I evaluate this code I get a Dictionary
in a "twisted" order:当我评估这段代码时,我得到一个“扭曲”顺序的
Dictionary
:
9 -> I
5 -> E
1 -> A
10 ->J
6 -> F
2 -> B
7 -> G
3 -> C
8 -> H
4 -> D
Each time a Dictionary
with the same entry data is created it have the same order, so I assume it is a feature not a bug..?每次创建具有相同条目数据的
Dictionary
时,它都具有相同的顺序,所以我认为这是一个功能而不是错误..?
I use Pharo v9.0.21.我使用 Pharo v9.0.21。
A Dictionary is not an ordered collection.字典不是有序集合。 Instead it is a keyed collection, keeping key-value pairs.
相反,它是一个键控集合,保留键值对。
There is an OrderPreservingDictionary for you to use: https://github.com/pharo-contributions/OrderPreservingDictionary有一个 OrderPreservingDictionary 供你使用: https://github.com/pharo-contributions/OrderPreservingDictionary
In addition to this other answer is is worth explaining the apparent disorder shown in the question.除了这个其他答案值得解释问题中显示的明显混乱。
Firstly observe that Dictionary new: 10
will create a new instance of Dictionary
with capacity for a prime number p
of associations greater than 10
.首先观察
Dictionary new: 10
将创建一个新的Dictionary
实例,其容量为大于10
的素数p
的关联。 Say 11, 13, 17, whatever.说 11、13、17,随便什么。
Secondly, for every association added, the dictionary will compute the hash value of the key and deduce the location from its remainder modulo p
.其次,对于添加的每个关联,字典将计算键的 hash 值并从其余数模
p
推导出位置。
Since all keys occurring in the example are instances of SmallInteger
, their hashes will be themselves(*).由于示例中出现的所有键都是
SmallInteger
的实例,因此它们的哈希值将是它们自己 (*)。 And since these are smaller than p
, they will equal the modulo and hence be stored in the slots derived from their values in some implementation-dependent way.并且由于它们小于
p
,它们将等于模数,因此以某种依赖于实现的方式存储在从它们的值派生的槽中。
Finally, the printing method is free to enumerate the associations in any order.最后,打印方法可以自由地以任何顺序枚举关联。
(*) While this is true in some dialects, I've checked in Pharo and this is not true, 3 hash
is not 3
etc. which explains the "twisting" in the case of Pharo. (*) 虽然这在某些方言中是正确的,但我在 Pharo 中检查过这不是真的,
3 hash
不是3
等等,这解释了 Pharo 的“扭曲”。
For completeness of the answer there is such thing as ordered Dictnionary.为了答案的完整性,有有序的 Dictnionary 这样的东西。
At Smalltalk/X the #OrderedDictionary
is defined as:在Smalltalk/X中,
#OrderedDictionary
被定义为:
Dictionary subclass:#OrderedDictionary
instanceVariableNames:'order'
classVariableNames:''
poolDictionaries:''
category:'Collections-Sequenceable'
"/ I am a subclass of Dictionary whose elements (associations) are ordered in a
"/ similar fashion to OrderedCollection.
"/ That is, while being filled via #at:put: messages (or similar Dictionary protocol),
"/ the order in which associations are added, is remembered and accessible via the #atIndex:
"/ or #order messages.
"/ Therefore, this combines fast access via hashing with a defined order when enumerating.
"/
"/ [instance variables:]
"/ order <OrderedCollection> Ordered collection of keys reflecting the order of
"/ associations in the dictionary.
"/
"/ [complexity:]
"/ access by index: O(1)
"/ access by key: O(1)
"/ searching: O(n)
"/ insertion: mostly O(1)
"/ removal: mostly O(N) (because order will have O(n) behavior)
"/
"/ [author:]
"/ Ifor Wyn Williams
"/ Changed by: exept
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.