dcsimg
Results 1 to 22 of 22

Thread: sort Dictionary array....

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Italy-Napoli
    Posts
    1,761

    sort Dictionary array....

    in MyDict have this array:

    01-2017
    03-2014
    02-2017
    ...
    08/2012

    are month and year...

    how to sort and to have now:

    08/2012
    03-2014
    01-2017
    02-2017
    ...

  2. #2
    PowerPoster
    Join Date
    Oct 2013
    Posts
    3,185

    Re: sort Dictionary array....

    This is not possible with your current keys
    You have to write them in a different format, first the Year then followed by the Month

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Italy-Napoli
    Posts
    1,761

    Re: sort Dictionary array....

    ok...
    use instaed

    2017-01
    2014-03
    2017-02
    ...
    2012-01

  4. #4
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,794

    Re: sort Dictionary array....

    Quote Originally Posted by luca90 View Post
    ok...
    use instaed

    2017-01
    2014-03
    2017-02
    ...
    2012-01
    You could use the RC5-cSortedDictionary (which adds/contains Key/Value-pairs always sorted):

    Code:
    Option Explicit
     
    Private Sub Form_Load()
      Dim D As cSortedDictionary
      Set D = New_c.SortedDictionary
          
          'the cSortedDictionary is adding new Key/Values already sorted
          D.Add "2017-01", 1
          D.Add "2014-03", 2
          D.Add "2017-02", 3
          D.Add "2012-01", 4
          
      Dim i As Long 'so you can (at any time) enumerate a sorted List this way
      For i = 0 To D.Count - 1
        Debug.Print D.KeyByIndex(i), D.ItemByIndex(i)
      Next
    End Sub
    The above printing out:
    Code:
    2012-01        4 
    2014-03        2 
    2017-01        1 
    2017-02        3
    Olaf

  5. #5
    PowerPoster
    Join Date
    Feb 2006
    Posts
    19,158

    Re: sort Dictionary array....

    A Scripting.Dictionary is not an "array."

    They have many limitations.

    For example retrieving by index is not supported, all you can do is pull all of the items out as an array and index into that. This can be an expensive operation unless you want to iterate over all of the items.

    Items cannot be ordered, all you have is "garbage in, garbage out" ordering, i.e. items are always retrieved in the order they were added.

    Sure, you get the Exists() method, Keys() method, RemoveAll() method, and an option for case-sensitive Keys. And in some scenarios they can give better performance than a Collection, though improper use can squander that advantage and more.


    Choosing a Collection, Scripting.Dictionary, or something else depends entirely on how you use the data structure. Neither supports any kind of "sorting" per se, though with a Collection you at least have the option of building it by doing ordered insertion.

    Both normally have Key and Item values, but oddly you only showed a single datum. Are you sure you don't want a simple array?
    Last edited by dilettante; Dec 1st, 2017 at 12:08 PM.

  6. #6

    Thread Starter
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Italy-Napoli
    Posts
    1,761

    Re: sort Dictionary array....

    Quote Originally Posted by Schmidt View Post
    You could use the RC5-cSortedDictionary (which adds/contains Key/Value-pairs always sorted):

    Code:
    Option Explicit
     
    Private Sub Form_Load()
      Dim D As cSortedDictionary
      Set D = New_c.SortedDictionary
          
          'the cSortedDictionary is adding new Key/Values already sorted
          D.Add "2017-01", 1
          D.Add "2014-03", 2
          D.Add "2017-02", 3
          D.Add "2012-01", 4
          
      Dim i As Long 'so you can (at any time) enumerate a sorted List this way
      For i = 0 To D.Count - 1
        Debug.Print D.KeyByIndex(i), D.ItemByIndex(i)
      Next
    End Sub
    The above printing out:
    Code:
    2012-01        4 
    2014-03        2 
    2017-01        1 
    2017-02        3
    Olaf
    ERROR!
    see image
    Attached Images Attached Images  

  7. #7
    PowerPoster
    Join Date
    Oct 2013
    Posts
    3,185

    Re: sort Dictionary array....

    You have to download and install the vbRichClient5 library first.
    http://vbrichclient.com/#/en/Downloads.htm

  8. #8

    Thread Starter
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Italy-Napoli
    Posts
    1,761

    Re: sort Dictionary array....

    Quote Originally Posted by Arnoutdv View Post
    You have to download and install the vbRichClient5 library first.
    http://vbrichclient.com/#/en/Downloads.htm
    ok now work perfect!

    Dubt, if i distribuite a compiled appplication (sa MYAPP.exe, from IDE Vb6) another user can have the dll in c:\...\System32? or not?

  9. #9
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,794

    Re: sort Dictionary array....

    Quote Originally Posted by luca90 View Post
    ok now work perfect!

    Dubt, if i distribuite a compiled appplication (sa MYAPP.exe, from IDE Vb6) another user can have the dll in c:\...\System32? or not?
    You can ship the 3 RC5-BaseLibs regfree (e.g. in a \Bin\-SubFolder of your App-Path).

    I've explained the necessary steps already in a thread you initiated about SQLite-usage
    (in the last postings there: http://www.vbforums.com/showthread.p...t-installation)

    Olaf

  10. #10

  11. #11
    PowerPoster
    Join Date
    Feb 2006
    Posts
    19,158

    Re: sort Dictionary array....

    How about an alternative?

    Code:
    Option Explicit
    
    Private List As Collection
    
    Private Declare Function StrCSpn Lib "shlwapi" Alias "StrCSpnW" ( _
        ByVal lpStr As Long, _
        ByVal lpSet As Long) As Long
    
    Private Function InStrAny(ByRef Str As String, ByRef Delims As String) As Long
        Dim Length As Long
        Dim Pos As Long
        'Find position of first character from the set in Delims within Str.
        'Returns 0 if not found.
        Length = Len(Str)
        If Length > 0 Then
            Pos = StrCSpn(StrPtr(Str), StrPtr(Delims)) + 1
            If Pos <= Length Then InStrAny = Pos
        End If
    End Function
    
    Private Sub InsertAscending( _
        ByVal Collection As Collection, _
        ByRef Item As String)
        'Item values are MM-YYYY or MM/YYYY, leading zeros optional.
        Dim Min As Long, Middle As Long, Max As Long
        Dim Pos As Long, KeyValue As Double, TestItem As String
    
        With Collection
            If .Count = 0 Then
                .Add Item
            Else
                Min = 0
                Max = .Count - 1
                Pos = InStrAny(Item, "-/")
                KeyValue = CDbl(DateSerial(CInt(Mid$(Item, Pos + 1)), _
                                           CInt(Left$(Item, Pos - 1)), _
                                           1))
                Do Until Min > Max
                    Middle = (Min + Max) \ 2
                    TestItem = .Item(Middle + 1)
                    Pos = InStrAny(TestItem, "-/")
                    Select Case KeyValue - CDbl(DateSerial(CInt(Mid$(TestItem, Pos + 1)), _
                                                           CInt(Left$(TestItem, Pos - 1)), _
                                                           1))
                        Case Is > 0
                            Min = Middle + 1
                        Case Is < 0
                            Max = Middle - 1
                        Case 0
                            .Add Item, , , Middle + 1
                            Exit Sub
                    End Select
                Loop
                If Min = Middle Then
                    .Add Item, , Middle + 1
                Else
                    .Add Item, , , Middle + 1
                End If
            End If
        End With
    End Sub
    
    Private Sub Form_Load()
        Dim F As Integer
        Dim Item As String
        Dim I As Long
    
        Set List = New Collection
        With Text1
            F = FreeFile(0)
            Open "data.txt" For Input As #F
            Do Until EOF(F)
                Line Input #F, Item
                .SelText = Item & vbNewLine
                InsertAscending List, Item
            Loop
            Close #F
            .SelStart = 0
        End With
        'Now we have a "sorted" Collection:
        With Text2
            For I = 1 To List.Count
                .SelText = List.Item(I) & vbNewLine
            Next
            .SelStart = 0
        End With
    End Sub
    
    Private Sub Form_Resize()
        If WindowState <> vbMinimized Then
            With Label1
                Text1.Move 0, .Height, ScaleWidth / 2, ScaleHeight - .Height
                .Move Text1.Left, 0
            End With
            With Label2
                Text2.Move ScaleWidth / 2, .Height, ScaleWidth / 2, ScaleHeight - .Height
                .Move Text2.Left, 0
            End With
        End If
    End Sub
    Name:  sshot.png
Views: 106
Size:  2.5 KB
    Attached Files Attached Files

  12. #12
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,794

    Re: sort Dictionary array....

    Here is the same thing as above (using the same data.txt file, after placing it in c:\temp):

    Needs a reference to vbRichClient5 and a List1-ListBox:
    Code:
    Option Explicit
    
    Private Sub Form_Load()
      FillListFromFile List1, "c:\temp\data.txt"
    End Sub
    
    Private Sub FillListFromFile(Lst As ListBox, FileName As String)
      Dim D As cSortedDictionary, Line, i As Long
      Set D = New_c.SortedDictionary(UniqueKeys:=False)
     
      For Each Line In Split(New_c.FSO.ReadTextContent(FileName), vbCrLf)
        If Val(Line) Then D.Add CDate(Line), Line 'Keys are Dates, Values the orig. String
      Next
      
      Lst.Clear
      For i = 0 To D.Count - 1
        Lst.AddItem Format(D.KeyByIndex(i), "yyyy-mm") & "   (orig: " & D.ItemByIndex(i) & ")"
      Next
    End Sub
    The ListBox-result shows the (sorted as true VB-Dates) result:



    Olaf

  13. #13
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    663

    Re: sort Dictionary array....

    it is of course possible to sort "any" array, however you want, with any kind of different syntax, even with / and - mixed.
    but you would need to add your own "sort" algorithm, like quicksort, where you don't include the "3" index in the string into the sorting.
    of course you will need to "add" those exceptions and that would make the sorting a bit more slower.

    however, its not the best way, better use an array that is easy to use and fast to sort. and when you show the date, then you format it.
    you got all the suggestions you need from the other members,

    i just wanted to point out that "it is possible" to do.

  14. #14
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,794

    Re: sort Dictionary array....

    Quote Originally Posted by baka View Post
    it is of course possible to sort "any" array, ...
    Collections or Dictionaries are not Arrays (since they support Key/Value pairs -
    in other words: "a second Column" with additional Item- or Context-Data,
    which will then be sorted along with the Keys in a Collection or Dictionary-Sort).

    Quote Originally Posted by baka View Post
    ... with any kind of different syntax, even with / and - mixed.
    I was already trying to point out, that in this special case of the OP no complicated parsing is needed,
    since VBs CDate-conversion can handle all these cases (paste the line below into your Immediate-Window):
    Code:
    ?CDate("7-2014"),CDate("7/2014"),CDate("2014-7"),CDate("2014/7")
    Using the above CDate-Conversion, here's what Array-Sorting can do
    (but as said, with a loss of the contextual Info that was yet present in the Dictionary-approach).

    Code:
    Private Sub FillListFromFile2(Lst As ListBox, FileName As String)
      Dim SA() As String, i As Long
          SA = Split(New_c.FSO.ReadTextContent(FileName), vbCrLf)
     
      Dim AL As cArrayList: Set AL = New_c.ArrayList(vbDate) '<force vbDate
          AL.AddElements SA, 0, UBound(SA) 'auto-conv. String-Arr to vbDate
          AL.Sort
      
      Lst.Clear 'clear and re-fill the ListBox from the now sorted ArrayList
      For i = 0 To AL.Count - 1: Lst.AddItem Format(AL(i), "yyyy-mm"): Next
    End Sub


    Olaf

  15. #15
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,626

    Re: sort Dictionary array....

    Quote Originally Posted by Schmidt View Post
    Collections or Dictionaries are not Arrays (since they support Key/Value pairs -
    in other words: "a second Column" with additional Item- or Context-Data
    The underlying abstract concept upon which Dictionaries and Hash tables are based is called an associative array. In the simplest terms, it is a type of array where elements can be retrieved by their association with other objects and not an ordinal like an index.
    Last edited by Niya; Dec 3rd, 2017 at 12:16 AM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  16. #16
    Frenzied Member ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    1,296

    Re: sort Dictionary array....

    Hi,

    a diffrent approach.
    just load the Data to a Listbox and sort it
    Code:
    Option Explicit
    
    
    
    Private Sub Form_Load() 'Test
    List3.AddItem "01-2017"
    List3.AddItem "03-2014"
    List3.AddItem "02-2017"
    List3.AddItem "12/2017"
    List3.AddItem "11-2017"
    List3.AddItem "10-2017"
    List3.AddItem "7/2017"
    List3.AddItem "05-2017"
    List3.AddItem "5/2017"
    List3.AddItem "03-2017"
    List3.AddItem "08/2012"
    End Sub
    
    Private Sub Command3_Click()
     Dim s As String, s1 As String, z As String
       Dim i As Long, j As Long
          For i = 0 To List3.ListCount - 1
          'swap the / for -
             s = Replace(List3.List(i), "/", "-")
             s1 = ""
             For j = 1 To Len(s)
                z = Mid(s, j, 1)
                If Len(z) Then
                   s1 = s1 & z
                End If
            Next
             List2.AddItem Format$(s1, "yyyy-mm")
        Next
    End Sub
    
    Private Sub Command5_Click()
    
    'now sort the Dates
    
    Dim i As Integer, x As Integer, remove As Integer
    Dim date1 As String
    For i = List2.ListCount - 1 To 0 Step -1
      date1 = List2.List(i)
      remove = i
        For x = 0 To i - 1
         If DateValue(List2.List(x)) < DateValue(date1) Then
          date1 = List2.List(x)
          remove = x
         End If
        Next x
     List2.RemoveItem remove
     List2.AddItem date1
    Next i
    End Sub
    regards
    Chris
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  17. #17
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,794

    Re: sort Dictionary array....

    Quote Originally Posted by ChrisE View Post
    ... just load the Data to a Listbox and sort it ...
    I'll probably never understand the obsession, to handle even basic, data-related tasks in GUI-Controls.

    That's just wrong - such tasks should be done on the Data-Containers (which contain typed-values, not Strings).

    Here again, how to do it by using an ADO.Recordset:
    Code:
    Private Sub Form_Load() 'Test
    Dim Rs As Object, i As Long
    Set Rs = CreateObject("ADODB.Recordset")
        Rs.Fields.Append "Orig", vbString
        Rs.Fields.Append "Date", vbDate
        Rs.Open 'the above lines create a free-standing Rs with a String- and a Date-Column
        
        With Rs 'now add Records
          .AddNew 0, "01-2017": !Date = !Orig '<- convert from vbString to vbDate
          .AddNew 0, "03-2014": !Date = !Orig
          .AddNew 0, "02-2017": !Date = !Orig
          .AddNew 0, "12/2017": !Date = !Orig
          .AddNew 0, "11-2017": !Date = !Orig
          .AddNew 0, "10-2017": !Date = !Orig
          .AddNew 0, "7/2017":  !Date = !Orig
          .AddNew 0, "05-2017": !Date = !Orig
          .AddNew 0, "5/2017":  !Date = !Orig
          .AddNew 0, "03-2017": !Date = !Orig
          .AddNew 0, "08/2012": !Date = !Orig
        End With
        
        Rs.Sort = "Date Asc" 'sort the Rs by its Date-Column
        For i = 1 To Rs.RecordCount
          Rs.Absoluteposition = i
          Debug.Print Format(Rs!Date, "yyyy-mm"), "Orig-Value: "; Rs!Orig
        Next
    End Sub
    The above prints out:
    Code:
    2012-08       Orig-Value: 08/2012
    2014-03       Orig-Value: 03-2014
    2017-01       Orig-Value: 01-2017
    2017-02       Orig-Value: 02-2017
    2017-03       Orig-Value: 03-2017
    2017-05       Orig-Value: 05-2017
    2017-05       Orig-Value: 5/2017
    2017-07       Orig-Value: 7/2017
    2017-10       Orig-Value: 10-2017
    2017-11       Orig-Value: 11-2017
    2017-12       Orig-Value: 12/2017
    Olaf

  18. #18
    Frenzied Member ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    1,296

    Re: sort Dictionary array....

    Quote Originally Posted by Schmidt View Post
    I'll probably never understand the obsession, to handle even basic, data-related tasks in GUI-Controls.

    That's just wrong - such tasks should be done on the Data-Containers (which contain typed-values, not Strings).

    Olaf
    Hi Olaf,
    you used the Listbox in Post#12 and 14 ?
    thought that was what the OP wanted.

    regards
    Chris
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  19. #19
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    663

    Re: sort Dictionary array....

    ChrisE, that would work of course, but it is bad.
    the reason is that the list will update every time you change an item and that takes cpu and time, second you are using a sequential sort method, and while it works, its not the fastest way, and third as Schmidt already pointed out, we should always think performance, and in this case, we don't need strings, and if we don't need, then we should not use. of course we can do it in many ways, theres a lot of different ways to do this, but we should try to avoid bad code.
    just try to sort 100.000 items using your method and you will know what we mean.

  20. #20
    Frenzied Member ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    1,296

    Re: sort Dictionary array....

    Quote Originally Posted by baka View Post
    ChrisE, that would work of course, but it is bad.
    the reason is that the list will update every time you change an item and that takes cpu and time, second you are using a sequential sort method, and while it works, its not the fastest way, and third as Schmidt already pointed out, we should always think performance, and in this case, we don't need strings, and if we don't need, then we should not use. of course we can do it in many ways, theres a lot of different ways to do this, but we should try to avoid bad code.
    just try to sort 100.000 items using your method and you will know what we mean.
    Hi baka,

    i know it's bad Code, like I said I thought it was what the OP wanted.

    I would read the Data directly to a new Table or append to an exixting one
    The Table Data with format(yyyy-mm) already in place
    Code:
    Private Sub Command22_Click()
    Dim strSql As String
    
    'Insert to new Table
    ' strSql = "Select * Into tbl_Import From [data.txt] IN 'c:\' 'Text;'"
     
     'Append to Table
    strSql = "Insert Into tbl_ImportDate Select * From [data.txt] In 'C:\' 'Text;'"
     
    adoConnection.Execute strSql
    
    End Sub
    Image after ImportName:  ImportTest.JPG
Views: 68
Size:  20.0 KB

    regards
    Chris
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  21. #21
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,794

    Re: sort Dictionary array....

    Quote Originally Posted by ChrisE View Post
    Hi Olaf,
    you used the Listbox in Post#12 and 14 ?
    thought that was what the OP wanted.
    The OP didn't mention any ListBoxes IIRC...

    I've used the ListBoxes (already available in the vbRuntime) as "simple, but dumb renderers"
    (in my examples for the DataContainers, which did the conversion- and final sorting).

    If the Count of "Records" (or Key/Value-Pairs) is low (below 100 or so) - and no special Formatting is needed,
    then a VB.ListBox is often enough to (re-)render the potentially changed Content of such DataContainers (with a preceding List.Clear).

    But if the amount of data in the DataContainers is larger, then virtual List- or DataGrid-Views should be used
    (virtual GUI-ListControls do not hold any data, which is IMO the right thing to do).

    We have only two real virtual List-Controls (though slightly buggy ones) available with VB6:
    - the VB-DataGrid (not meaning the FlexGrid or the MSHFlex)
    - and the VB-DataRepeater

    And both are not really as flexible as they could be, since they support only a single,
    bindable DataContainer-Type (ADO-Recordsets).

    The whole thing boils down not as much to performance (which is usually better with virtual Controls and bound data-sources),
    but to a separation of what belongs to:
    - the "Model" ... and ...
    - the "View"

    All modern GUI-development approaches have a clear separation in that regard
    (WebApps with modern js-Frameworks among them).

    Olaf

  22. #22
    Frenzied Member ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    1,296

    Re: sort Dictionary array....

    Quote Originally Posted by Schmidt View Post
    The OP didn't mention any ListBoxes IIRC...

    I've used the ListBoxes (already available in the vbRuntime) as "simple, but dumb renderers"
    (in my examples for the DataContainers, which did the conversion- and final sorting).

    If the Count of "Records" (or Key/Value-Pairs) is low (below 100 or so) - and no special Formatting is needed,
    then a VB.ListBox is often enough to (re-)render the potentially changed Content of such DataContainers (with a preceding List.Clear).

    But if the amount of data in the DataContainers is larger, then virtual List- or DataGrid-Views should be used
    (virtual GUI-ListControls do not hold any data, which is IMO the right thing to do).

    We have only two real virtual List-Controls (though slightly buggy ones) available with VB6:
    - the VB-DataGrid (not meaning the FlexGrid or the MSHFlex)
    - and the VB-DataRepeater

    And both are not really as flexible as they could be, since they support only a single,
    bindable DataContainer-Type (ADO-Recordsets).

    The whole thing boils down not as much to performance (which is usually better with virtual Controls and bound data-sources),
    but to a separation of what belongs to:
    - the "Model" ... and ...
    - the "View"

    All modern GUI-development approaches have a clear separation in that regard
    (WebApps with modern js-Frameworks among them).

    Olaf
    ups sorry, my mistake then.

    regards
    Chris
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width