arrays - 证明 Excel VBA Scripting.Dictionary 不保留项目插入顺序

标签 arrays excel dictionary vba

我正在尝试决定是否为我的项目使用 Excel VBA 集合或字典。由于多种原因,我倾向于字典,但我一直在阅读,当使用 For.. Each 循环检索字典项目或从字典 Items() 数组中读取项目时,检索顺序可能会不同。不是添加项目的顺序。这对我的应用程序来说将是一个严重的问题,因此我尝试了许多测试用例,试图证明这种顺序不匹配确实发生了。到目前为止,我还无法创建发生这种情况的场景,包括以随机顺序添加和删除项目。

任何人都可以提供一个示例来证明 Excel VBA Scripting.Dictionary 的检索顺序与插入顺序不匹配吗?

最佳答案

没有人可以提供 Scripting.Dictionary 的示例对象以与添加顺序不同的顺序返回键/项目,因为 Scripting.Dictionary 不会这样做。绝不。如果您按渐进顺序添加以下键/项目对,那么这就是它们的返回方式。

key  item
 1    A
 2    B
 3    C
 4    D

'enumerate by key
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")

dict.Add Key:=1, Item:="A"
dict.Add Key:=2, Item:="B"
dict.Add Key:=3, Item:="C"
dict.Add Key:=4, Item:="D"

Dim k As Variant
For Each k In dict.Keys
    Debug.Print k & " - " & dict.Item(k)
Next k

您可能指的是添加键的简写“覆盖”方法,而不检查它们是否存在。如果您尝试 .Add存在 key 时会抛出错误 457。但是,如果您只是写 KeysItems如果该键不存在,则将在字典中创建一个新键和项目,但如果该键存在,则该键保持不变并且该项目将被覆盖。

key  item
 1    A
 2    B
 3    C
 4    D
 2    E

'enumerate by key
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")

dict.Item(1) = "A"
dict.Item(2) = "B"
dict.Item(3) = "C"
dict.Item(4) = "D"
dict.Item(2) = "E"     'the second entry's item is overwritten

Dim k As Variant
For Each k In dict.Keys
    Debug.Print k & " - " & dict.Item(k)
Next k

覆盖方法比检查 key 是否快一点 .Exists但这种行为应该被理解。我使用覆盖来有意检索具有重复键的列表中任何键的最后一项,但这是一种特殊情况。请注意,2 .Key没有打乱原来的顺序;它只是有它的.Item替换为后一个。

如果您已添加 Microsoft Scripting Runtime 引用库,则可以使用 Early Binding在你的变量声明中。这样做的好处是可以创建稍微更快的字典对象并公开索引枚举的其他方法。

Dim dict As New Scripting.Dictionary

'enumerate by index position (zero-based index)
Dim i As Long
For i = 0 To dict.Count - 1
    Debug.Print dict.Keys(i) & " - " & dict.Items(i)
Next i

'enumerate as elements of an array
Dim a As Long
For a = LBound(dict.Keys) To UBound(dict.Keys)
    Debug.Print dict.Keys(a) & " - " & dict.Items(a)
Next a

fwiw,当字典的 .Count 时,我发现这个索引枚举不可靠。超过有符号整数 (32,767)。

最后, key /元素对可以一次删除一个或一次全部删除。

dict.Remove 2                              'remove by key

dict.Remove dict.Keys(0)                   'remove first key/item by index position
dict.Remove dict.Keys(UBound(dict.Keys))   'remove last key/item by index position

dict.RemoveAll                             'remove all

关于arrays - 证明 Excel VBA Scripting.Dictionary 不保留项目插入顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37705421/

相关文章:

excel - VBA数据透视表错误

python - 机器学习: working with array of objects in preprocessing

c - 字符指针预增

c - 如果不使用整数,我怎么能写这个呢?

javascript - 检查数组是否有不同的元素

java - 修改ArrayList中的对象

vba - Excel VBA设置范围来自字符串变量

php - Spreadsheet_excel_reader 日期格式

scala - Groovy 集合的映射方法

dictionary - 从 map[string]string 获取单个键值