Sign in to follow this  
Followers 0
BugFix

Sort an 2D-Array in both dimensions

9 posts in this topic

#1 ·  Posted (edited)

Hi,

i must sort a lot of screen coordinates in an 2D-array. But i can sort only by X or only by Y. I want to sort by X and for same X-values sort by Y.

Thats why i've made this function.

I got the idea for this solution by working with RegEx. The detection of sortable values is like RegEx's positive and negative lookahead. :shocked:

Edit:

- Add new parameter $REVERSE

- Now you can sort 2nd dimension reverse to 1st dimension

Edit2:

Now it works for all occurences in 2nd dimension.

CODE
;------------------------------------------------------------------------------------------------------------
;   Function        _ArraySort_2ary(ByRef $ARRAY [, $DIM_1ST=0 [, $DESCENDING=0 [$REVERSE=False]]])
;
;   Description     sort an 2D-Array 2-ary
;                   BaseIndex is 0
;                   sort the whole array
;
;   Parameter       $ARRAY:         Array to sort
;       optional    $DIM_1ST:       MainSortIndex; 1st Dim. [0] or last occurence in 2nd Dim.[all other values] (default 0)
;       optional    $DESCENDING:    Sort ascending[0]/descending[1] (default 0)
;       optional    $REVERSE:       Sort 2nd Dimension reverse to 1st Dimension (default False)
;
;   Return          Succes          ByRef 2-ary sorted Array
;                   Failure         0  set @error
;                                   @error = 1  given array is not array
;                                   @error = 2  given array has only 1 dimension
;
;   Requirements    By using numeric entry, be sure that type is "number" for correct sort
;                   Works with any occurences in 2nd Dimension
;                   
;   Author          BugFix (bugfix@autoit.de)
;------------------------------------------------------------------------------------------------------------
#include <Array.au3>
Func _ArraySort_2ary(ByRef $ARRAY, $DIM_1ST=0, $DESCENDING=0, $REVERSE=False)
    If ( Not IsArray($ARRAY) ) Then
        SetError(1)
        Return 0
    EndIf
    Local $FIRST = 0, $LAST, $tmpFIRST, $sortYES = 0
    Local $UBound2nd = UBound($ARRAY,2)
    If @error = 2 Then
        SetError(2)
        Return 0
    EndIf
    If $DIM_1ST <> 0 Then $DIM_1ST = $UBound2nd-1
    Local $arTmp[1][$UBound2nd]
    _ArraySort($ARRAY,$DESCENDING,0,0,$UBound2nd,$DIM_1ST)
    If $REVERSE Then
        Switch $DESCENDING
            Case 0
                $DESCENDING = 1
            Case 1
                $DESCENDING = 0
        EndSwitch
    EndIf
    For $u = 0 To $UBound2nd-1
        For $i = 0 To UBound($ARRAY)-1
            If $sortYES = 0 Then
                If $u > 0 Then
                    If ( $i < UBound($ARRAY)-1 ) And ( $ARRAY[$i][$u] = $ARRAY[$i+1][$u] ) And _
                        ( $ARRAY[$i][$u-1] = $ARRAY[$i+1][$u-1] )Then
                        $sortYES = 1
                        $FIRST = $i
                    EndIf
                Else
                    If ( $i < UBound($ARRAY)-1 ) And ( $ARRAY[$i][$u] = $ARRAY[$i+1][$u] ) Then
                        $sortYES = 1
                        $FIRST = $i
                    EndIf
                EndIf
            ElseIf $sortYES = 1 Then
                If ( $i = UBound($ARRAY)-1 ) Or ( $ARRAY[$i][$u] <> $ARRAY[$i+1][$u] ) Then 
                    $sortYES = 0
                    $LAST = $i +1
                    ReDim $arTmp[$LAST-$FIRST][$UBound2nd]
                    $tmpFIRST = $FIRST
                    For $k = 0 To UBound($arTmp)-1 
                        For $l = 0 To $UBound2nd-1
                            $arTmp[$k][$l] = $ARRAY[$tmpFIRST][$l]
                        Next
                        $tmpFIRST += 1
                    Next
                    $tmpFIRST = $FIRST
                    Switch $DIM_1ST
                        Case 0
                            If $u = $UBound2nd-1 Then
                                _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,$UBound2nd-1)
                            Else
                                _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,$u+1)
                            EndIf
                            For $k = 0 To UBound($arTmp)-1
                                For $l = 1 To $UBound2nd-1
                                    $ARRAY[$tmpFIRST][$l] = $arTmp[$k][$l]
                                Next
                                $tmpFIRST += 1
                            Next                    
                        Case $UBound2nd-1
                            If $u = $UBound2nd-1 Then
                                _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,0)
                            Else
                                _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,$UBound2nd-1-$u-1)
                            EndIf
                            For $k = 0 To UBound($arTmp)-1
                                For $l = 0 To $UBound2nd-2
                                    $ARRAY[$tmpFIRST][$l] = $arTmp[$k][$l]
                                Next
                                $tmpFIRST += 1
                            Next                
                    EndSwitch
                EndIf
            EndIf
        Next
        $sortYES = 0
    Next
EndFunc ;==>_ArraySort_2ary

_ArraySort_2ary.au3

Edited by BugFix

Best Regards BugFix  

Share this post


Link to post
Share on other sites



Share this post


Link to post
Share on other sites

Thanks for your feedback. :">

Hi,

Nice, thanks,

I may change my func in Array2D if you agree. [in my sig...]

Best, Randall

Hi Randall, it's OK to use it in your library.

Best Regards BugFix  

Share this post


Link to post
Share on other sites

@BugFix VERY nice work!!

@Randallc Let us know when your UDF is changed.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

New Parameter added: $REVERS

Now you can sort one Dimension revers to sort direction of the other one.

See my first post.


Best Regards BugFix  

Share this post


Link to post
Share on other sites

Hi,

Although it loks to be better coding than used, I realised it did not do what I expected; I think it only sorts on 2 columns, whereas my function sorts on as many columns as I want. Is that correct? if not, could you post an example like mine [subsort example in the Array2D link in my sig] which shows how?

Thanks, Randall

Share this post


Link to post
Share on other sites

Hi,

Although it loks to be better coding than used, I realised it did not do what I expected; I think it only sorts on 2 columns, whereas my function sorts on as many columns as I want. Is that correct? if not, could you post an example like mine [subsort example in the Array2D link in my sig] which shows how?

Thanks, Randall

You're right. At time it works only with 2 occurences in 2nd dimension. Sry, that i've forgotten to say it in my first post. Expand it to all occurences is on my ToDoList.

Best Regards BugFix  

Share this post


Link to post
Share on other sites

Well, now its done.

You can sort 2D-array with any occurences in second dimension.

I've tested it for a while and it works fine. But now it's early in the morning ( or deep at night ? :rambo: 2:10 AM).

Thats why i think it will be better, if some awake people test it. :rolleyes:

Please give me your feedback. Thanks.

Code, see my 1st post.


Best Regards BugFix  

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  
Followers 0