【问题标题】:How do I clone a Dictionary object?如何克隆 Dictionary 对象?
【发布时间】:2010-06-11 11:03:42
【问题描述】:

我在 VBScript 中有一个 Dictionary 对象。如何将其中包含的所有对象复制到新的Dictionary,即创建字典的克隆/副本?

【问题讨论】:

    标签: dictionary vbscript clone


    【解决方案1】:

    创建一个新的Dictionary 对象,遍历原字典中的键并将这些键和对应的值添加到新字典中,如下所示:

    Function CloneDictionary(Dict)
      Dim newDict
      Set newDict = CreateObject("Scripting.Dictionary")
    
      For Each key in Dict.Keys
        newDict.Add key, Dict(key)
      Next
      newDict.CompareMode = Dict.CompareMode
    
      Set CloneDictionary = newDict
    End Function
    

    这在大多数情况下应该足够了。但是,如果您的原始字典包含对象,则您必须实现深度克隆,即同时克隆这些对象。

    【讨论】:

    • 是的,这是真的..但是是否有任何内置功能可以执行深度克隆
    • 感谢这很好用,奇怪它不是 VBA 语言的一部分...
    • 注意,在向新字典添加数据之前需要设置.CompareMode
    【解决方案2】:

    如果有人正在寻找 VBA 解决方案,以下函数会执行字典的“深度克隆”,包括嵌套的字典对象。

    ' Compare mode for cloning dictionary object
    ' See CloneDictionary function
    Public Enum eCompareMethod2
        ecmBinaryCompare = 0
        ecmTextCompare = 1
        ecmDatabaseCompare = 2
        ' Added this to use original compare method
        ecmSourceMethod = 3
    End Enum
    
    
    '---------------------------------------------------------------------------------------
    ' Procedure : CloneDictionary
    ' Author    : Adam Waller
    ' Date      : 3/30/2021
    ' Purpose   : Recursive function to deep-clone a dictionary object, including nested
    '           : dictionaries.
    '           : NOTE: All other object types are cloned as a reference to the same object
    '           : referenced by the original dictionary, not a new object.
    '---------------------------------------------------------------------------------------
    '
    Public Function CloneDictionary(dSource As Dictionary, _
        Optional Compare As eCompareMethod2 = ecmSourceMethod) As Dictionary
    
        Dim dNew As Dictionary
        Dim dChild As Dictionary
        Dim varKey As Variant
    
        ' No object returned if source is nothing
        If dSource Is Nothing Then Exit Function
    
        ' Create new dictionary object and set compare mode
        Set dNew = New Dictionary
        If Compare = ecmSourceMethod Then
            ' Use the same compare mode as the original dictionary.
            dNew.CompareMode = dSource.CompareMode
        Else
            dNew.CompareMode = Compare
        End If
        
        ' Loop through keys
        For Each varKey In dSource.Keys
            If TypeOf varKey Is Dictionary Then
                ' Call this function recursively to add nested dictionary
                Set dChild = varKey
                dNew.Add varKey, CloneDictionary(dChild, Compare)
            Else
                ' Add key to dictionary
                dNew.Add varKey, dSource(varKey)
            End If
        Next varKey
        
        ' Return new dictionary
        Set CloneDictionary = dNew
        
    End Function
    

    【讨论】:

      【解决方案3】:

      查看VBScript: How to utiliize a dictionary object returned from a function? 中接受的答案。如果只需要参考,这可能是一个解决方案。

      编辑根据 Ekkehard.Horner 的评论,我现在明白这不是克隆,但可能会帮助其他只想参考原始对象的人。

      【讨论】:

      • 字典是对象,将对象传递给 Subs/Functions/Methods(即使使用 ByVal)、将对象分配给值以及从 Functions/Method(希望使用 Set)返回对象将始终 i> 处理引用,从不克隆/复制/创建新对象。因此,请删除您的误导/错误答案。
      猜你喜欢
      • 2010-11-08
      • 2012-11-17
      • 2010-09-07
      • 2012-12-07
      • 1970-01-01
      • 2011-11-07
      • 2017-05-22
      • 1970-01-01
      • 2013-01-03
      相关资源
      最近更新 更多