How do I clone a Dictionary object?
Asked Answered
S

4

10

I have a Dictionary object in VBScript. How can I copy all the objects contained in it to a new Dictionary, i.e. create a clone/duplicate of the dictionary?

Sapanwood answered 11/6, 2010 at 11:3 Comment(0)
Z
12

Create a new Dictionary object, iterate through the keys in the original dictionary and adds these keys and the corresponding values to the new dictionary, like this:

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

This should be enough in most cases. However, if your original dictionary holds objects, you'll have to implement deep cloning, that is, clone these objects as well.

Zionism answered 11/6, 2010 at 11:37 Comment(3)
Yes thats true..but is there any built in functionality to perform deep cloningSapanwood
Thanks this works well, strange its not part of VBA language...Siding
Note that you need to set the .CompareMode before adding data to the new dictionary.Arly
A
1

If anyone is looking for a VBA solution, the following function performs a "deep-clone" of a dictionary, including nested dictionary objects.

' 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
Arly answered 31/3, 2021 at 0:17 Comment(0)
B
0

Or you can just :

Set dTEM = dEQP

;)

Bulky answered 2/7, 2023 at 8:49 Comment(1)
What are these variable names dTEM and dEQP. Add an additional explanation to your answer, please.Alaynaalayne
A
-2

Take a look at the accepted answer in VBScript: How to utiliize a dictionary object returned from a function?. Could be a solution if a reference is all that is being looked for.

Edit As per Ekkehard.Horner's comment, I understand now that this is not cloning, but may help others who are only looking for a reference to the original object.

Atalee answered 4/11, 2012 at 14:36 Comment(1)
Dictionaries are objects and passing objects to Subs/Functions/Methods (even with ByVal), assigning objects to values, and returning objects from Functions/Method (hopefully with Set) will always deal with references and never clone/copy/create a new object. So please delete your misleading/wrong answer.Semibreve

© 2022 - 2024 — McMap. All rights reserved.