Jump to content
Sign in to follow this  
yoinkster

Sorting arrays

Recommended Posts

yoinkster

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? :)

Share this post


Link to post
Share on other sites
KaFu

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

Share this post


Link to post
Share on other sites
SmOke_N

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.

Share this post


Link to post
Share on other sites
KaFu

#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

Share this post


Link to post
Share on other sites
KaFu

Share this post


Link to post
Share on other sites
yoinkster

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

??

Share this post


Link to post
Share on other sites
KaFu

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).

Share this post


Link to post
Share on other sites
SmOke_N

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.

Share this post


Link to post
Share on other sites
KaFu

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

Standard Consultant naming convention for files YYMMDD_Title_AUTHORSHORTCUT_VERSION.doc :)

Share this post


Link to post
Share on other sites
yoinkster

#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:

Share this post


Link to post
Share on other sites
KaFu

Share this post


Link to post
Share on other sites
yoinkster

No problem :lmao: ... just PM the address for the final bill :)

123 Fake Street,

Springfield USA.

If you have problems locating it, ask Police Chief Clancy Wiggum, he's been there :think:

Share this post


Link to post
Share on other sites
SmOke_N

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.

Share this post


Link to post
Share on other sites
KaFu

Share this post


Link to post
Share on other sites
KaFu

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

Nice :lmao:, the Art of RegEx, makes coding easier in many ways... still another thing to master for me :)

Share this post


Link to post
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
Sign in to follow this  

×