VBA-Better-Array icon indicating copy to clipboard operation
VBA-Better-Array copied to clipboard

How to copyFromDictionary?

Open winner106 opened this issue 5 years ago • 3 comments

hi,please,i want to copyfromdictionary,just like copyfromrange.

what I have tried :

Dim arrResult As New BetterArray
arrResult.Items = dict.keys
arrResult.Transpose
arrResult.Push dict.Items

But it didn't work.

I expected result is: a 2d array,(two columns), the first Column is The dictionary keys,the second is items,

Could you please do some help? Many Thanks.

I feel very upset for my poor English.🥺

winner106 avatar Jan 29 '21 18:01 winner106

Hi

This isn't actually something I have a method for built-in. I definitely should do though so I will probably add a Zip function like Python has this weekend!

Here's a quick first draft which should do what you want:

Public Sub ZipTest()
    Dim Dict As Object
    Set Dict = CreateObject("Scripting.Dictionary")
    Dict.Add "A", 1
    Dict.Add "B", 2
    Dict.Add "C", 3
    
    
    Dim Joined As BetterArray
    Set Joined = Zip(Dict.Keys, Dict.Items)
    
    Debug.Print Joined.ToString(True)
    
End Sub

Private Function Zip(ByRef LeftList As Variant, ByRef RightList As Variant) As BetterArray
    Dim LeftLower As Long
    Dim LeftUpper As Long
    Dim RightLower As Long
    Dim RightUpper As Long
    Dim MinIndex As Long
    Dim MaxIndex As Long
    Dim i As Long
    Dim LeftElementIsArray As Boolean
    Dim RightElementIsArray As Boolean
    Dim Result As BetterArray
    Dim Temp As BetterArray
    
    Set Result = New BetterArray
    Set Temp = New BetterArray
    
    LeftLower = LBound(LeftList)
    LeftUpper = UBound(LeftList)
    RightLower = LBound(RightList)
    RightUpper = UBound(RightList)
    MinIndex = Temp.Min(LeftLower, RightLower)
    MaxIndex = Temp.Max(LeftUpper, RightUpper)
    Result.LowerBound = MinIndex
    For i = MinIndex To MaxIndex
        If i < LeftLower Or i > LeftUpper Then
            ' outside bounds of left array - right only
            Result.Push RightList(i)
        ElseIf i < RightLower Or i > RightUpper Then
            ' outside bounds of right array - left only
            Result.Push LeftList(i)
        Else
            ' current index within bounds of both arrays
            LeftElementIsArray = IsArray(LeftList(i))
            RightElementIsArray = IsArray(RightList(i))
            
            If LeftElementIsArray And RightElementIsArray Then
                Temp.Concat LeftList(i), RightList(i)
            ElseIf LeftElementIsArray Or RightElementIsArray Then
                If LeftElementIsArray Then
                    Temp.Items = LeftList(i)
                    Temp.Push RightList(i)
                Else
                    Temp.Items = RightList(i)
                    Temp.Unshift LeftList(i)
                End If
            Else
                Temp.Push LeftList(i)
                Temp.Push RightList(i)
            End If
            Result.Push Temp.Items
            Temp.ResetToDefault
        End If
    Next
    Set Zip = Result
End Function

It needs more work (and test coverage) before I can add it in a proper release but like I say I will probably put something together this weekend.

I feel very upset for my poor English.🥺

Don't be silly, your English is fine :)

Senipah avatar Jan 29 '21 21:01 Senipah

Thanks for your reply. I really appreciate for your sharing!

about the solution

I finaly found I can do it this way :

    Dim arrResult As New BetterArray
    arrResult.Items = Array(dicKeywords.keys, dicKeywords.Items)
    arrResult.Transpose

Maybe this can save your weekend time 🌝 but maybe some performance problem. it's up to you... Thank you again.

but remind: in dictionary ,maybe the item is a jagged array

winner106 avatar Jan 30 '21 00:01 winner106

hi, Can your VBA zip do this like Python zip?

image

winner106 avatar Feb 01 '21 02:02 winner106