1

I have a dictionary object that needs to be sorted, but the keys are date values in the form

['Apr. 2013','May 2013','Feb. 2013',
'Mar. 2013','Jul. 2013','Aug. 2013',
'Sep. 2013','Oct. 2013','Jun. 2013','Nov. 2013']

As you can see, the dates are out of order. The corresponding value to each key is a number. I want to sort them in chronological order. However, since the months are string values, and since months are not alphabetically in order, I cannot just sort them automatically. Also, though not shown in the code sample, there may be years that are not 2013 as well. How would I go about sorting this dictionary?

Thanks in advance!

Globmont
  • 881
  • 2
  • 8
  • 20

3 Answers3

1

Code stolen from here:

  Const csSep = "|"
  Const cnMax = 100

  Dim sInp : sInp = "Apr. 2013|May. 2013|Apr. 2014|Feb. 2013|Apr. 2011|Mar. 2013|Jul. 2013|Aug. 2013"
  Dim aInp : aInp = Split(sInp, csSep) ' YourDic.Keys
  WScript.Echo "A:", vbCrLf & Join(aInp, vbCrLf)
  WScript.Echo "---------------------"

  Dim oNAL : Set oNAL = CreateObject( "System.Collections.ArrayList" )
  Dim oSB  : Set oSB  = CreateObject( "System.Text.StringBuilder" )
  Dim sWord
  For Each sWord In aInp
      Dim dtCmp : dtCmp = CDate(sWord) ' depends on regional/locale settings
      oSB.AppendFormat_3 "{0:yyyy-MM}{1}{2}", dtCmp, csSep, sWord
      sWord = oSB.ToString()
      oSB.Length = 0
      oNAL.Add sWord
  Next
  oNAL.Sort

  ReDim aOut(oNAL.Count - 1)
  Dim i
  For i = 0 To UBound(aOut)
      aOut(i) = Split(oNAL(i), csSep)(1)
  Next
  WScript.Echo "B:", vbCrLf & Join(aOut, vbCrLf)

output:

A:
Apr. 2013
May. 2013
Apr. 2014
Feb. 2013
Apr. 2011
Mar. 2013
Jul. 2013
Aug. 2013
---------------------
B:
Apr. 2011
Feb. 2013
Mar. 2013
Apr. 2013
May. 2013
Jul. 2013
Aug. 2013
Apr. 2014

The theory is (c) R. L. Schwartz (see Schwartzian transform).

Update wrt Martha's answer (and my caveat):

Don't have to much confidence in VBScript's date conversions:

>> WScript.Echo CDate("Dez 2013")
>>
Error Number:       13  ' <-- can't read german
Error Description:  Type mismatch

>> WScript.Echo CDate("Dec 2013") ' <-- can read english
>>
01.12.2013 ' <-- can write german

>> WScript.Echo DateValue("Dez 2013")
>>
Error Number:       13 ' <-- DateValue isn't more intelligent
Error Description:  Type mismatch
Community
  • 1
  • 1
Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96
1

The DateValue() function is pretty smart about recognizing dates, no matter how crazily they're formatted. It certainly has no trouble recognizing "Apr. 2013" as 4/1/2013. So in your sort routine, instead of comparing the keys, compare their DateValues.

Martha
  • 3,932
  • 3
  • 33
  • 42
0

I would replace each key with the respective formula:

newKey = year * monthRank

monthRank would be 1 for January, 2 for February and so on. newKey could then be used to sort every value. Of course this implys that you would have to parse the old keys in order to identify the monthRank and year, but converting the data from an unstructured data format to a sturctured one includes a cost you have to pay.

Hope I helped!

Pantelis Natsiavas
  • 5,293
  • 5
  • 21
  • 36