Jump to content

Sorting arrays


Recommended Posts

Hey guys, I have an array, say of 4 elements. They are all in the form of

$array[1] = XXXXX_X_FEB09.TOC
$array[2] = XXXXX_X_DEC08.TOC
$array[3] = XXXXX_X_NOV08.TOC
$array[4] = XXXXX_X_JAN09.TOC

Although potentially the XXXXX_X could sometimes be XXXXXX or anything else, the elements will always end with MMMYY.TOC so I can sort of half see how you could extract the bit you need to look at but not how to sort it.

Anyone got any ideas? :)

Link to comment
Share on other sites

Create a 2-D array. D-1 contains the original value, D-2 needs to be filled with a reconstructed split of the desired sort criteria. Additionally you'll need to create a ref for the month's name.

D2 = YYMM

where YY = 08 or 09

and month needs to be 01, 02... transscript from JAN, FEB...

Result should look something like

$array[1][0] = XXXXX_X_FEB09.TOC        $array[1][1] = 0902
$array[2][0] = XXXXX_X_DEC08.TOC        $array[2][1] = 0812     
$array[3][0] = XXXXX_X_NOV08.TOC        $array[3][1] = 0811 
$array[4][0] = XXXXX_X_JAN09.TOC        $array[4][1] = 0901

Finally sort the 2-D array on D2...

Edited by KaFu
Link to comment
Share on other sites

  • Moderators

Create a 2-D array. D-1 contains the original value, D-2 needs to be filled with a reconstructed split of the desired sort criteria. Additionally you'll need to create a ref for the month's name.

D2 = YYMM

where YY = 08 or 09

and month needs to be 01, 02... transscript from JAN, FEB...

Result should look something like

$array[1][0] = XXXXX_X_FEB09.TOC        $array[1][1] = 0902
$array[2][0] = XXXXX_X_DEC08.TOC        $array[2][1] = 0812     
$array[3][0] = XXXXX_X_NOV08.TOC        $array[3][1] = 0811 
$array[4][0] = XXXXX_X_JAN09.TOC        $array[4][1] = 0901

Finally sort the 2-D array on D2...

That is "sort of" the correct method, but the issue with the logic is, you could get a sort like:

0811 = August 2011

0812 = August 2012

0901 = September 2001

0902 = September 2002

When the desired output would have been:

0901

0902

0811

0812

Doing this type of sorting would require "Year" sort first, then month, then match. So a 3D array would work, but I'm not sure that AutoIt supports 3D arrays for _ArraySort().

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

#include <array.au3>
dim $array[11]

$array[1] = 'XXXXX_X_FEB09.TOC'
$array[2] = 'XXXXX_X_DEC08.TOC'
$array[3] = 'XXXXX_X_NOV08.TOC'
$array[4] = 'XXXXX_X_JAN09.TOC'
$array[5] = 'XXXXX_X_SEP08.TOC'
$array[6] = 'XXXXX_X_MAR08.TOC'
$array[7] = 'XXXXX_X_JUL08.TOC'
$array[8] = 'XXXXX_X_OCT07.TOC'
$array[9] = 'XXXXX_X_JAN08.TOC'
$array[10] = 'XXXXX_X_FEB07.TOC'

Dim $array_2D[UBound($array)][2]
for $i = 1 to UBound($array) - 1
    $array_2D[$i][0] = $array[$i]
    Switch StringUpper(stringleft(stringright($array[$i],9),3))
        Case 'JAN'
            $month = '01'
        Case 'FEB'
            $month = '02'
        Case 'MAR'
            $month = '03'
        Case 'APR'
            $month = '04'
        Case 'MAY'
            $month = '05'
        Case 'JUN'
            $month = '06'
        Case 'JUL'
            $month = '07'
        Case 'AUG'
            $month = '08'
        Case 'SEP'
            $month = '09'
        Case 'OCT'
            $month = '10'
        Case 'NOV'
            $month = '11'
        Case 'DEC'
            $month = '12'
        Case Else
            $month = '00'
    EndSwitch
    $array_2D[$i][1] = stringleft(stringright($array[$i],6),2) & $month
Next

_ArrayDisplay($array_2D)
_ArraySort($array_2D,0,0,0,1)
_ArrayDisplay($array_2D)

And as usual this still needs some more error checking :) ...

Edited by KaFu
Link to comment
Share on other sites

I understand what KaFu said but not what SmOke_N said.

If you generate D2 with the year first and then the month you will always be able to sort this numerically to get the lowest year and lowest month at the start so I'm not sure what SmOke_N because surely the D2 elements wouldn't be what he put ::

0811 = August 2011

0812 = August 2012

0901 = September 2001

0902 = September 2002

but would be

1108 = August 2011

1208 = August 2012

0109 = September 2001

0209 = September 2002

??

Link to comment
Share on other sites

I understand what KaFu said but not what SmOke_N said.

SmOke_N assumed I recommended MMYY format.... updated example above, didn' really switch the month, value in first example was always 01 :) (copy&paste).

Link to comment
Share on other sites

  • Moderators

SmOke_N assumed I recommended MMYY format.... updated example above, didn' really switch the month, value in first example was always 01 :) (copy&paste).

Ahh, you switched the month and the year around, unique approach :lmao:

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Link to comment
Share on other sites

#include <array.au3>
dim $array[11]

$array[1] = 'XXXXX_X_FEB09.TOC'
$array[2] = 'XXXXX_X_DEC08.TOC'
$array[3] = 'XXXXX_X_NOV08.TOC'
$array[4] = 'XXXXX_X_JAN09.TOC'
$array[5] = 'XXXXX_X_SEP08.TOC'
$array[6] = 'XXXXX_X_MAR08.TOC'
$array[7] = 'XXXXX_X_JUL08.TOC'
$array[8] = 'XXXXX_X_OCT07.TOC'
$array[9] = 'XXXXX_X_JAN08.TOC'
$array[10] = 'XXXXX_X_FEB07.TOC'

Dim $array_2D[UBound($array)][2]
for $i = 1 to UBound($array) - 1
    $array_2D[$i][0] = $array[$i]
    Switch StringUpper(stringleft(stringright($array[$i],9),3))
        Case 'JAN'
            $month = '01'
        Case 'FEB'
            $month = '02'
        Case 'MAR'
            $month = '03'
        Case 'APR'
            $month = '04'
        Case 'MAY'
            $month = '05'
        Case 'JUN'
            $month = '06'
        Case 'JUL'
            $month = '07'
        Case 'AUG'
            $month = '08'
        Case 'SEP'
            $month = '09'
        Case 'OCT'
            $month = '10'
        Case 'NOV'
            $month = '11'
        Case 'DEC'
            $month = '12'
        Case Else
            $month = '00'
    EndSwitch
    $array_2D[$i][1] = stringleft(stringright($array[$i],6),2) & $month
Next

_ArrayDisplay($array_2D)
_ArraySort($array_2D,0,0,0,1)
_ArrayDisplay($array_2D)

And as usual this still needs some more error checking :) ...

I think you just saved me a few weeks work !! :lmao:

Link to comment
Share on other sites

  • Moderators

Standard Consultant naming convention for files YYMMDD_Title_AUTHORSHORTCUT_VERSION.doc :)

:lmao:

Here's a fun way making it a udf using your type of wrap month/year method:

#include <array.au3>
dim $array[11]

$array[1] = 'XXXXX_X_FEB09.TOC'
$array[2] = 'XXXXX_X_DEC08.TOC'
$array[3] = 'XXXXX_X_NOV08.TOC'
$array[4] = 'XXXXX_X_JAN09.TOC'
$array[5] = 'XXXXX_X_SEP08.TOC'
$array[6] = 'XXXXX_X_MAR08.TOC'
$array[7] = 'XXXXX_X_JUL08.TOC'
$array[8] = 'XXXXX_X_OCT07.TOC'
$array[9] = 'XXXXX_X_JAN08.TOC'
$array[10] = 'XXXXX_X_FEB07.TOC'

$a_check = _my_date_sort($array)
_ArrayDisplay($a_check)

Func _my_date_sort($a_array, $f_descending = 0, $i_base = 1)
    If IsArray($a_array) = 0 Then Return SetError(1, 0, 0)
    
    Local $sz_my = "JAN01FEB02MAR03APR04MAY05JUN06JUL07AUG08SEP09OCT10NOV11DEC12"
    
    Local $i_ub = UBound($a_array)
    Local $a_temp[$i_ub][2], $s_temp, $a_sre
    
    For $i = $i_base To $i_ub - 1
        $a_sre = StringRegExp($a_array[$i], "(?i).*?([a-z]+)(\d+)\.\w+\z", 1)
        If @error Then Return SetError(2, 0, 0) ; File format wasn't correct
        
        $s_temp = $a_sre[1]
        $a_sre = StringRegExp($sz_my, "(?i)" & $a_sre[0] & "(\d+)", 1)
        
        If @error Then
            $s_temp &= "00"
        Else
            $s_temp &= $a_sre[0]
        EndIf
        
        $a_temp[$i][0] = $a_array[$i]
        $a_temp[$i][1] = $s_temp
    Next
    
    _ArraySort($a_temp, $f_descending, $i_base, 0, 1)
    
    Local $a_ret[$i_ub]
    For $i = $i_base To $i_ub - 1
        $a_ret[$i] = $a_temp[$i][0]
    Next
    
    Return $a_ret
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...